python中的埃拉托色尼问题的值错误

发布于 2024-10-21 08:59:39 字数 573 浏览 2 评论 0原文

这是我的埃拉托色尼筛法的版本,用于查找 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

惯饮孤独 2024-10-28 08:59:39

您在迭代时修改 mylist 。这会产生奇怪的结果。在第一次运行循环期间,i 将被分配列表的第一项,即 2。然后,该语句

p = mylist.pop(0)

从列表的开头删除此项,并且 p 也设置为 2。接下来,您的检查 i % p == 0 将产生 True,并且您尝试从列表中删除 i,但它已经消失了,导致您引用的错误消息。

这个循环的完整逻辑似乎被打破了。对于遇到的每个素数,您需要从列表中删除该素数的所有倍数。您通常需要两个嵌套循环来实现此目的。

此外,您的函数

def number_list(n):
    mylist = []
    for i in range(2,n+1):
        mylist.append(i)
    return mylist

相当于

def number_list(n):
    return range(2, n + 1)

,即您根本不需要此函数,只需使用 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 statement

p = mylist.pop(0)

removes this very item from the beginning of the list, and p is also set to 2. Next, your check i % p == 0 will yield True, and you try to remove i 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

def number_list(n):
    mylist = []
    for i in range(2,n+1):
        mylist.append(i)
    return mylist

is equivalent to

def number_list(n):
    return range(2, n + 1)

i.e. you would not need this function at all, just use range(2, n + 1) instead.

简单 2024-10-28 08:59:39

这是埃拉托斯特尼筛法的工作代码。范围对象必须创建为列表,因为我们需要删除项目。

def all_primes_to(n):
    numbers = list(range(2,n+1))
    primes = []
    while numbers:
        prime = numbers.pop(0)
        primes.append(prime)
        remove_multiples(numbers, prime)
    return primes

def remove_multiples(lst, x):
    length = len(lst)
    i = 0
    while i < length:
        if lst[i] % x == 0:
            del lst[i]
            length -= 1
        i += 1

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.

def all_primes_to(n):
    numbers = list(range(2,n+1))
    primes = []
    while numbers:
        prime = numbers.pop(0)
        primes.append(prime)
        remove_multiples(numbers, prime)
    return primes

def remove_multiples(lst, x):
    length = len(lst)
    i = 0
    while i < length:
        if lst[i] % x == 0:
            del lst[i]
            length -= 1
        i += 1
绅刃 2024-10-28 08:59:39

不确定,但我认为您不应该修改正在迭代的列表。
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.

窝囊感情。 2024-10-28 08:59:39

这里提到的具体x实际上是i(如上行所示)。

堆栈跟踪通常还会为您提供行号,因此知道这一点后应该很容易进行调试。

无论哪种方式,这里的问题是您试图多次删除某些项目。您可以使用 if i in mylist 轻松修复它,但我建议您查看筛子的完整实现,以获得更快/更优化(更重要的是,工作)的版本。它可能会让您对 Python 的工作原理有一些额外的了解。

The specific x mentioned here is actually i (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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文