搜索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个素数。顺便说一句,第二个代码似乎是一个无限循环,如何阻止它?
感谢和抱歉这么多问题。
答案 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问题,我会继续猜测筛子会更好。