python中的埃拉托色尼问题的值错误
这是我的埃拉托色尼筛法的版本,用于查找 n 以内的素数。我觉得它应该可以工作,但我收到一个错误,我不太明白为什么:
mylist.remove(i)
ValueError: list.remove(x): x not in list
为什么它提到 x?
这是代码:
def number_list(n):
mylist = []
for i in range(2,n+1):
mylist.append(i)
return mylist
def sieve():
n = eval(input("What is the maximum limit? "))
mylist = number_list(n)
primes = []
for i in mylist:
p = mylist.pop(0)
primes.append(p)
if i % p == 0:
mylist.remove(i)
return primes
Here's my version of the Sieve of Eratosthenes for finding prime numbers up to a limit n. I feel like it should work but I get an error and I don't really understand why:
mylist.remove(i)
ValueError: list.remove(x): x not in list
Why does it mention x?
Here's the code:
def number_list(n):
mylist = []
for i in range(2,n+1):
mylist.append(i)
return mylist
def sieve():
n = eval(input("What is the maximum limit? "))
mylist = number_list(n)
primes = []
for i in mylist:
p = mylist.pop(0)
primes.append(p)
if i % p == 0:
mylist.remove(i)
return primes
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您在迭代时修改
mylist
。这会产生奇怪的结果。在第一次运行循环期间,i
将被分配列表的第一项,即2
。然后,该语句从列表的开头删除此项,并且
p
也设置为2
。接下来,您的检查i % p == 0
将产生True
,并且您尝试从列表中删除i
,但它已经消失了,导致您引用的错误消息。这个循环的完整逻辑似乎被打破了。对于遇到的每个素数,您需要从列表中删除该素数的所有倍数。您通常需要两个嵌套循环来实现此目的。
此外,您的函数
相当于
,即您根本不需要此函数,只需使用
range(2, n + 1)
即可。You are modifying
mylist
while iterating over it. This will yield strange results. During the first run of your loop,i
will be assigned the first item of your list, i.e.2
. Then, the statementremoves this very item from the beginning of the list, and
p
is also set to2
. Next, your checki % p == 0
will yieldTrue
, and you try to removei
from the list, but it is already gone, resulting in the error message you cited.The complete logic of this loop seems to be broken. For each prime you encounter, you need to remove all multiples of that prime from the list. You usually need two nested loops to achieve this.
Furthermore, your function
is equivalent to
i.e. you would not need this function at all, just use
range(2, n + 1)
instead.这是埃拉托斯特尼筛法的工作代码。范围对象必须创建为列表,因为我们需要删除项目。
Here is a working code for the Sieve of Eratosthenes. The range object must be made to a list because we need to delete items.
不确定,但我认为您不应该修改正在迭代的列表。
Perl 中是禁止的,也许 Python 在这种情况下也是类似的。
另一件事是我会为您的所有项目列表使用生成器。
您使用的方法会耗尽大“n”的内存。
Not sure but i think you shouldn't modify list you're iterating over.
It's forbidden in perl, maybe python is similar in this case.
Another thing is that I would use generators for your all item list.
Approach you're using will blow memory for big 'n's.
这里提到的具体
x
实际上是i
(如上行所示)。堆栈跟踪通常还会为您提供行号,因此知道这一点后应该很容易进行调试。
无论哪种方式,这里的问题是您试图多次删除某些项目。您可以使用
if i in mylist
轻松修复它,但我建议您查看筛子的完整实现,以获得更快/更优化(更重要的是,工作)的版本。它可能会让您对 Python 的工作原理有一些额外的了解。The specific
x
mentioned here is actuallyi
(as seen on the line above).Stacktraces normally also give you line numbers so it should be easy to debug knowing that.
Either way, the problem here is that you are trying to remove some items more than once. You can easily fix it with a
if i in mylist
but I recommend you look at a complete implementation of the sieve to get a faster/more optimized (and more importantly, working) version. It might give you some extra insight on how Python works.