[英]prime number generation code in python
我正在尝试以下方法来生成素数:
primes = [2]
candidate = 3
MILLION = 1000000
while candidate < MILLION:
if all(candidate % prime for prime in primes if prime**2 <= candidate):
primes.append(candidate)
candidate += 2
但是,这比我以前的代码要慢得多,在我以前的代码中我没有使用all
函数,而是自己进行检查,如下所示:
primes = [2]
candidate = 3
MILLION = 1000000
while candidate < MILLION:
can_be_prime = True
for p in primes:
if p**2 > candidate:
break
elif candidate % p == 0:
can_be_prime = False
break
if can_be_prime:
primes.append(candidate)
candidate += 2
当第二个在10秒内结束时,第一个要花很长时间才能完成。 有人可以帮助我理解为什么第一个数字在第一个100000个数字之后开始如此缓慢地输出吗?
当你的想法,使用发电机表达缩短了代码和any
好,他们是不等价的。 特别是,在较长的解决方案中,您要迭代素数的(排序的)列表,并在找到p ** 2 > candidate
为真的素数后立即中断迭代。
但是,在生成器表达式中, x for p in primes if p ** 2 <= candidate
,则尝试使用x for p in primes if p ** 2 <= candidate
进行此检查。 不幸的是,这是不一样的。 即使检查失败,发电机仍会继续遍历剩下的素数,执行的是p ** 2
每单质,在外部的每次迭代 while
循环。
如果您编写的方式有所不同,则可以验证这是问题所在:
def getPrimes (candidate):
for p in primes:
if p ** 2 > candidate:
break
yield p
while candidate < MILLION:
if all(candidate % prime for prime in getPrimes(candidate)):
primes.append(candidate)
candidate += 2
因此,现在,我们在较长版本中使用相同的想法,并在达到p ** 2 > candidate
为真的primes
终止primes
的迭代。 这样,我们可以从更长的解决方案中获得更快的速度。
我们实际上可以使用6n +/- 1
规则生成素数。 例如,如果要生成给定数字的质数:
def primes(N):
if N == 2:
primes = [2]
elif N >= 3:
primes = [2, 3]
else:
return None
for i in range(6, N):
if i % 6 == 0:
left = i - 1
right = i + 1
if all(left % p != 0 for p in primes):
primes.append(left)
if all(right % p != 0 for p in primes):
primes.append(right)
return primes
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.