Python素数生成器收益率与收益率

时间:2013-06-30 21:03:53

标签: python return primes yield

搜索python素数生成器,我发现:

def primes(n): 
    if n==2: return [2]
    elif n<2: return []
    s=range(3,n+1,2)
    mroot = n ** 0.5
    half=(n+1)/2-1
    i=0
    m=3
    while m <= mroot:
        if s[i]:
            j=(m*m-3)/2
            s[j]=0
            while j<half:
                s[j]=0
                j+=m
        i=i+1
        m=2*i+3
    return [2]+[x for x in s if x]

print primes(13)
print primes(3000)

还有:

def get_primes(number):
    while True:
        if is_prime(number): #is_prime is defined somewhere else
            yield number
        number += 1

什么更有效,返回列表或yield命令?为什么?考虑一下我正在寻找非常大量的素数,比如前1000个素数。顺便说一句,第二个代码似乎是一个无限循环,如何阻止它?

感谢和抱歉这么多问题。

1 个答案:

答案 0 :(得分:4)

这实际上取决于你想要对素数列表做什么。

首先,正如Martijn指出的那样,第一个算法是一个非常聪明的主筛,第二个算法测试每个素数。如果您对快速素数算法感兴趣,我会查找几个不同的素数筛,以尝试更好地理解该方法。最简单的是Eratosthenes的Sieve。

无论如何,我认为这不是你的问题。你真的在寻找普通Python函数和生成器之间的区别。有很多关于SO的问题和大量的文档可以很好地解释生成器是什么。

当我查看你的问题时,

This出现在侧边栏中,我想这会有所帮助。或者只是在文档中搜索“generator”。

快速解释是你的第一个函数返回一个素数列表,最多为n。获得该列表后,您可以在需要时访问其中的任何成员,在整个列表中调用函数等。第二种方法是生成器。它不返回一个列表 - 这会返回一个迭代器,它会根据需要提供下一个素数。因此,如果您一次需要一个素数,或者为了在每个素数上调用一个函数,迭代器可能是好的。但是,如果您需要按需访问素数,则不会这样做。

如果您正在寻找符合某些标准的第一个素数,那么生成器就是好的,因为您不必指定范围。如果你只需要前100个,没有理由产生前千个素数。

例如:

for prime in get_primes(2):
    if meets_condition(prime):
        return prime

会好于:

primeList = primes(1000)
for prime in primeList:
    if meets_condition(prime):
        return prime

如果n很小,但如果n接近1000,则不是。

得走了,对不起。我稍后会扩展并校对。查找发电机和主要筛子!

如果您正在处理projecteuler.com问题,我会继续猜测筛子会更好。