Python list.remove for循环“x not in list”

时间:2013-07-01 20:49:26

标签: python list pycharm

我正在尝试用Python创建一个主筛。

我从制作一个从2到2000的列表开始。我想用支票迭代所有素数,并从列表中删除所有素数的倍数。

我还没有绕过素数循环,但是我有一个方法从数字2开始,并删除它的所有倍数。

primes=list(range(2,2001))
p=2

while p<len(primes):
    for x in range (p*p, len(primes), p):
        primes.remove(x)
    print(primes)

这张照片:[...] 1989,1991,1993,1995,1997,1999,2000]

正如你所看到的,数字2000仍然存在,而且不应该是。

Traceback (most recent call last):
  File "C:/Users/Are/PycharmProjects/Project Euler/10.py", line 8, in <module>
    primes.remove(x)
ValueError: list.remove(x): x not in list

我的推理出了什么问题?

我正在使用PyCharm,有没有办法让我在出错时打印x的值?

4 个答案:

答案 0 :(得分:5)

你的清单不是2000年,你从2开始......

>>> primes=list(range(2,2001))
>>> print len(primes)
1999

因此,当你执行while循环时,它不会达到2000 ......:)

答案 1 :(得分:4)

您创建了1999个元素的列表:

>>> len(range(2,2001))
1999

然后循环遍历range(),但不包括该长度:

for x in range (p*p, len(primes), p):

因此x永远不会比1998年更大。

而不是len(primes),使用上限常量:

limit = 2001
primes=list(range(limit))

# ...

for x in range (p*p, limit, p):

下一个问题是您继续使用while p<len(primes):循环;您将生成不再 primes列表中的一部分的数字,因此无法再次删除它们。您可以使用异常处理程序来捕获异常:

try:
    primes.remove(x)
except ValueError:
    # already removed
    pass

但您可能想重新考虑while循环条件。

答案 2 :(得分:2)

range(a,b)中,第一个值为a,最后一个值为b-1。 在您的情况下,这意味着您只是迭代到len(primes)-1,小于2000

答案 3 :(得分:1)

崩溃时x的值实际为4.您不会将p递增到第一个循环结束时列表中的下一个值。

其次,您尝试从列表中多次删除值。您将(例如)尝试删除12次。一旦你在2上迭代,一旦你在3上迭代。

最后,您按照列表的长度进行操作,当您从中移除值时,该列表的长度始终会变小。你第一次绕过循环,你的列表大小确实非常小。

重新编写代码:

primes=list(range(2,2001))
p=2

while p<2000:
    for x in range (p*p, 2001, p):
        if x in primes:
            primes.remove(x)
    while 1:
        p = p + 1
        if p in primes or p > 2000:
            break

print primes