Python 有人能解释为什么这种寻找素数的方法比我的快得多吗?

Python 有人能解释为什么这种寻找素数的方法比我的快得多吗?,python,time,process,generator,primes,Python,Time,Process,Generator,Primes,我几天前才开始编程,试图解决一个涉及大量素数的问题。下面是我提出的方法,但是对于大量的数据,它的速度很慢: import time import math t0=time.clock() a=100000 ##preprimes is the list of primes up to sqrt(a) that will be ##divided into the larger list lista preprimes=[] lista= list(range(1,a)) prelis

我几天前才开始编程,试图解决一个涉及大量素数的问题。下面是我提出的方法,但是对于大量的数据,它的速度很慢:

import time
import math

t0=time.clock()

a=100000

##preprimes is the list of primes up to sqrt(a) that will be
##divided into the larger list lista


preprimes=[]

lista= list(range(1,a))
prelista= list(range(1,round(math.sqrt(a))))

def predivisors(a):
    x=a-1
    suma=0
    while (x>0):
        if a%x==0:
            suma=suma+x
            x=x-1
            if suma==1:
                preprimes.append(a)
        else:
            x=x-1          

for x in prelista:
    predivisors(x)


for n in preprimes:
    for num in lista:
        if num%n==0:
            lista.remove(num)

print(sum(lista)+sum(preprimes)-1 )
print(time.clock()-t0, ' seconds')
此方法需要81秒才能返回多达10万个素数的总和。我在网上找到的以下方法对于同一任务需要0.38秒:

import math
import time

t0=time.clock()

n=100000

def getPrimes(n):
    """returns set of all primes below n"""
    non_primes = [j for j in range(4, n, 2)] # 2 covers all even numbers
    for i in range(3, n, 2):
        non_primes.extend([j for j in range(i*2, n, i)])
    return set([i for i in range(2, n)]) - set(non_primes)


def getCircularPrimes(n):
    primes = getPrimes(n)
    is_circ = []
    for prime in primes:

        prime_str = str(prime)
        iter_count = len(prime_str) - 1

        rotated_num = []
        while iter_count > 0:
            prime_str = prime_str[1:] + prime_str[:1]
            rotated_num.append(int(prime_str))
            iter_count -= 1

        if primes >= set(rotated_num):
            is_circ.append(prime)


    return len(is_circ)

print(sum(getPrimes(n)))
##print(sorted(getPrimes(n)))

print('process took ',time.clock()-t0,'seconds')

为什么第二种方法比我的快那么多?什么因素决定了一个过程需要多长时间?

在您的方法中,您根据
n
对一个
n
数字列表与另一个基于
n
的大型数字列表进行评估。 在这样做的过程中,你会执行大量的任务

for n in preprimes:
    for num in lista:
        if num%n==0:
            lista.remove(num)
我相信这将导致时间复杂度在
O(n^2)
范围内

在在线方法中,我认为它的复杂性更接近于
O(n)


随着输入的增加,
O(n)
O(n^2)
在运行时的差异急剧增加。

我相信第二种方法是使用埃拉托斯的seive(sp?),这几乎是计算我发现的素数的最快方法(至少我可以实现)顺便提一下,这里有一个简单的技巧---->
isPrime=lambda n:~-2**n%n==1
请注意,
getCircularTimes
函数是一个令人费解的问题,它不在任何地方调用,也不用于素数的计算。我想这是因为你的remove函数。当你在删除一个元素后使用该函数时,之后的所有其他元素都会被移动,这需要时间。不确定这是否明显是dup,但问题是相同的:我们已经实现了试用划分,实现了Eratosthenes筛选,还有一个问题,为什么前者在算法上比后者慢。其他一切在这里都无关紧要。但前提是你真的知道如何阅读代码。我认为这意味着,如果这不是dup,那么这不是SO的问题,属于另一个SE站点,但我很容易被说服。@JoranBeasley:筛子绝对不是计算素数的最快方法。对于巨大的素数,有更好的算法(上面提到了一些)。当然,对于较小的素数,一个查找表(或一个N**.25的轮子)是最好的解决方案你能简单解释一下在线代码中getPrimes(n)函数是如何工作的吗?