Python 为什么第一种方法要比第二种方法慢得多,计算素数之和?

Python 为什么第一种方法要比第二种方法慢得多,计算素数之和?,python,performance,primes,Python,Performance,Primes,我在解决一个Euler的项目问题(用python)时,我必须计算200万以下所有素数的总和,我想出了两个解决方案,但只有一个得到了结果,因为另一个太慢了。这是我的第一个太慢的解决方案: n=2000000 list = list(range(2,n,1)) for x in list : if(x*x>n): break for d in range(x,n,x): if((x!=d) and (d in list) ):

我在解决一个Euler的项目问题(用python)时,我必须计算200万以下所有素数的总和,我想出了两个解决方案,但只有一个得到了结果,因为另一个太慢了。这是我的第一个太慢的解决方案:

n=2000000
list = list(range(2,n,1))

for x in list :
    if(x*x>n):
        break

    for d in range(x,n,x):
        if((x!=d) and (d in list) ):
            list.remove(d)
            continue


result=sum(list)        
print(result)
这是我的第二个解决方案,它在计算总和时非常快:

n=2000000
list = list(range(2,n,1))
temp=list
for x in list :
    if(x*x>n):
        break
    if(temp[x-2]==0):
        continue
    for d in range(x,n,x):
        if(x!=d):
            temp[d-2]=0

result=sum(list)        
print(result)

我想知道的是,为什么最后一个几乎是在瞬间计算出总和,而另一个在几分钟后甚至没有产生结果?

查找代码中的循环数。在第一个解决方案中,对于列表中的x,您有大约4个循环
对于范围(x,n,x)中的d:
(列表中的d)
列表。remove(d)
还通过循环列表来删除d。但在第二个解决方案中,对于列表中的x只有两个循环:
和范围(x,n,x)中的d只有两个循环:

您已经优化了算法。祝贺您。
(列表中的d)
对您的第一个代码段的运行没有帮助,而且在您调用
list.remove()
时,您可能会遇到一个
索引器
。您不应该使用变量名
list
,因为它会覆盖内置的
列表
。另外,执行
test=list
是毫无意义的,因为两个变量都指向内存中的同一个列表,编辑其中一个变量将编辑另一个变量。是的,确实如此<代码>(列表中的d)是列表的O(n)操作,它已经在双嵌套for循环中。在第二个代码段中没有相同的操作。让我们通过一个示例来理解这一点。假设n=10,在第一种情况下,执行的语句总数是10*10*10*10=10000,在第二种情况下,它是10*10=100,你可以引用它,就像快速找到所有素数,然后你可以添加它们。您还可以在这里@RodrigoPina了解更多关于这种算法的信息。如果您想提高性能,您可以从原始列表中删除您确信不是素数的数字,即除数字2之外的所有偶数。