[英]Python list.remove for loop “x not in list”
我正在尝试在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的值?
您的列表不长2000,从2开始。
>>> primes=list(range(2,2001))
>>> print len(primes)
1999
因此,当您执行while循环时,它最多不会达到2000 ... :)
您创建了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
循环条件。
在range(a,b)
,第一个值为a
,最后一个值为b-1
。 在您的情况下,这意味着您仅迭代len(primes)-1
,该值小于2000
。
崩溃时的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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.