Python 3:超过 100 个索引的列表在索引 47 之后循环。为啥?我该如何阻止这个?
Posted
技术标签:
【中文标题】Python 3:超过 100 个索引的列表在索引 47 之后循环。为啥?我该如何阻止这个?【英文标题】:Python 3: List of over 100 indices cycles back around after index 47. why? how do I stop this?Python 3:超过 100 个索引的列表在索引 47 之后循环。为什么?我该如何阻止这个? 【发布时间】:2017-05-13 04:29:36 【问题描述】:所以这是一个获取第 n 个素数的函数。我知道它以前做过,而且我的方法可能不是很有效(新编码器顺便说一下过去的小涉足)。 无论如何,下面的代码工作并返回所提供索引的素数。 即:
ind = 4
final[1,2,3,5,7,11]
return final[ind-1]
returns: 5
但是 final[51-1] 返回 final[3-1] 中的内容。似乎在索引 47 之后它会循环回来并重新开始。我已经打印了包含在最终列表中的整个列表。它会打印每个素数,甚至是那些超过 47 的素数。我不确定发生了什么。 python中的列表有限制吗?
代码如下:
def nthPrime(ind): #gets nth prime number. IE: 5th prime == 11. works based off very in-efficient version of Sieve of Eratosthenes. but in increments of 200
p =
T = 2
incST = 2
incEND = incST + 200
final=[1]
while len(final) < ind:
for i in range(incST,incEND):
p[i] = True
while T <= math.sqrt(incEND):
l = 0
while l <= incEND:
p[T**2 + (T*l)] = False
l+=1
if T**2+(T*l) > incEND:
break
for k,v in p.items():
if p[k] == True and k > T:
T = int(k)
break
for k in p:
if p[k] == True:
final.append(k)
incST = incEND + 1
incEND = incST + 200
'''
currently function works perfectly for
any index under 48.
at index 48 and above it seems to start
back at index 1.
IE: final[51]
^would actually return final[4]
'''
return final[ind-1]
【问题讨论】:
如果您尝试用语言(尽可能简短地)解释您的方法是什么,以及您是如何尝试实现它的,那么错误可能会很快被发现。 您可以随时在 www.pythontutor.com 上可视化您的 Python 代码,以找出问题所在。 【参考方案1】:这不是 Python 问题,问题在于您如何计算结果。当您执行final[51]
时,它实际上会返回持有该位置的值,请执行以下操作:
# Modify your line
# return final[ind-1]
# return final
# Call your method
o_final = nthPrime(100)
for k in range(len(o_final)):
print(k, y[k])
然后你意识到在 pos 93
你到达下一个并继续递增。
【讨论】:
这似乎是它应该做的。nthPrime(4)
应该只返回第 4 个素数,而不是前 4 个素数。【参考方案2】:
您需要计算列表中有多少个素数,但是您在循环中累积了final
,因此您在循环中将所有数字加到了限制数次。在 199 之后再次从 2 开始。
另外,使用字典和依赖顺序是危险的。您应该在迭代时对它们进行排序。
我的解决方案只计算素数以知道何时结束循环,并在最后组成列表,省略 1 并将索引移动 1。
我在迭代字典时也会对字典进行排序,以确保:
import math
def nthPrime(ind): #gets nth prime number. IE: 5th prime == 11. works based off very in-efficient version of Sieve of Eratosthenes. but in increments of 200
p =
T = 2
incST = 2
incEND = incST + 200
lenfinal = 1
while lenfinal < ind:
for i in range(incST,incEND):
p[i] = True
while T <= math.sqrt(incEND):
l = 0
while l <= incEND:
p[T**2 + (T*l)] = False
l+=1
if T**2+(T*l) > incEND:
break
for k,v in sorted(p.items()):
if v and k > T:
T = int(k)
break
incST = incEND + 1
incEND = incST + 200
# compute length, no need to order or to actually create the list
lenfinal = sum(1 for k,v in p.items() if v)
# now compose the list
final = [k for k,v in sorted(p.items()) if v]
return final[ind-2]
【讨论】:
哇。很棒的反应。 哇。很棒的回应。我从中学到了很多。不仅仅是我做错了什么。但我也不知道您不必明确说明 v== True。也不知道您可以在创建列表中执行 if 语句。谢谢。这行得通。 是的,几乎是codereview.stackexchange.com 的候选人。我不确定(我确定相反)生成整个列表以获取一个 1 元素是否未优化。嗯,它有效。我不会选择字典而是选择list
,以避免不必要的散列。
是的,我正在挑战。关键是效率。我知道我与此相去甚远。这是我第一次尝试这个特殊的挑战。最终结果需要能够快速得到第 n 个素数,其中 n=200000。当我在 IDLE 中运行此代码并将其传递 200000 作为要获取的索引时,它就坐在那里。所以......是的......将不得不再试一次。
一旦成功,不要犹豫,将工作代码发布到codereview.stackexchange.com 并请求帮助。寻求更好的性能也是这里的主题。你也可以在那里找到我:)【参考方案3】:
一个更有效的方法是递归函数: 我会在代码中做一些解释。
def nthPrime(ind):
first_prime=1 #first prime number
number = 1 # all numbers that we will check, this will be incremented
prime_numbers = [first_prime] # The list of prime numbers we will find
def findPrimeInPosition(ind, number):
if ind > len(prime_numbers): # This recursive function will exit if find a sufficient number of primes
number+=1 # incrementing to check the next number
is_prime = True # Assuming number is a prime
for p in prime_numbers[1:]: # Check if it is a prime
if not number % p:
is_prime = False
if is_prime:
prime_numbers.append(number) # Add to the list of primes
findPrimeInPosition(ind, number)
return prime_numbers[-1] # Get the last element found
return findPrimeInPosition(ind, number)
使用示例:
print nthPrime(47)
>> 199
print nthPrime(48)
>> 211
【讨论】:
这看起来确实更整洁。我现在在玩它。谢谢。我会看看我是否可以发布我的原始和你的时间比较。 所以...在较低的索引下它似乎确实稍快一些。不过,我无法测试出更高的指数。 Python 开始抛出 ind = 2000 的错误: RecursionError: maximum recursion depth exceeded in comparison 这需要能够处理 LARGE 数字。至少到第 200,000 个索引。 所以我将递归函数更改为 while 循环。您的代码将时间几乎缩短了一半。 >>> OP.nthPrime(47) [211, 0.004000425338745117] >>> OP.nthPrime2(47) [211, 0.003000497817993164] >>> OP.nthPrime(2000) [17539, 11.65716552734325] >>0> OP. ) [17389, 6.237623691558838] >>> 太好了,while 循环确实可以完成这项工作。以上是关于Python 3:超过 100 个索引的列表在索引 47 之后循环。为啥?我该如何阻止这个?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 python 3.4 tkinter“索引错误:列表索引超出范围”中修复此错误