因为OP要求高效率实现,这是对活动状态2002码作者:David Eppstein/Alex Martelli(见他的回答): 不要在词典中记录质数的信息,直到候选人看到它的正方形。..将空间复杂性降低到下面O(平方吨(N)而不是O(N),对于产生的n个素数(π(sqrt(N Log N) ~ 2平方米(n对数)/2平方吨(n对数) ~ 2平方米(n/log n))。因此,时间复杂度也得到了改善,即它跑得更快.
创建一个“滑动筛”作为每个基质数的当前倍数(即低于当前生产点的sqrt)的字典,以及它们的步进价值:from itertools import count # ideone.com/aVndFMdef postponed_sieve():
# postponed sieve, by Will Ness
yield 2; yield 3; yield 5; yield 7; # original code David Eppstein,
sieve = {} # Alex Martelli, ActiveState Recipe 2002
ps = postponed_sieve() # a separate base Primes Supply:
p = next(ps) and next(ps) # (3) a Prime to add to dict
q = p*p # (9) its sQuare
for c in count(9,2): # the Candidate
if c in sieve: # c's a multiple of some base prime
s = sieve.pop(c) # i.e. a composite ; or
elif c < q:
yield c # a prime
continue
else: # (c==q): # or the next base prime's square:
s=count(q+2*p,2*p) # (9+6, by 6 : 15,21,27,33,...)
p=next(ps) # (5)
q=p*p # (25)
for m in s: # the next multiple
if m not in sieve: # no duplicates
break
sieve[m] = s # original test entry: ideone.com/WFv4f
(此处较旧的原始代码是经过编辑以包含更改的,如答案通过蒂姆·彼得斯(见下文)。另见这,这个进行相关的讨论。
相似2-3-5-7轮-基于代码快2.15倍(这与理论上的改进非常接近。3/2 * 5/4 * 7/6 = 2.1875).