【发布时间】:2012-03-06 10:42:26
【问题描述】:
下面的代码是pythonic生成素数的吗?
def get_primes(n):
primes=[False,False]+[True]*(n-1)
next_p=(i for i,j in enumerate(primes) if j)
while True:
p=next(next_p)
yield p
primes[p*p::p]=[False]*((n-p*p)//p+1)
请注意,next(next_p) 最终会抛出一个 StopIteration 错误,该错误会以某种方式结束函数 get_primes。这很糟糕吗?
还要注意 next_p 是一个迭代素数的生成器,但是素数在迭代过程中会发生变化。那是不是很糟糕的风格?
添加以下 if 语句可使前一百万个素数的时间小于 0.25 秒:
if p*p<=n:
primes[p*p::p]=[False]*((n-p*p)//p+1)
【问题讨论】:
-
如果你想使用
primes=[False,False]+[True]*(n-1),你可以节省一行,同时增加复杂性,你可以优化使用半个筛子,跳过偶数。见stackoverflow.com/a/3035188/464543 -
在我的机器上测试你的代码是否为 0,1,2,3 而没有
if p*p<=n:... 在我的机器上不需要该行 -
谢谢,我忘了 [False]*(non positive) = []
-
查看this question,了解python中用于快速生成素数的许多示例
-
感谢 Kimvais,我用那里的代码测试了我的代码,我的速度慢了大约 30 倍,但我希望强调“pythonic”而不是速度。