[英]prime number generation code in python
I'm trying the following approach for generating primes: 我正在尝试以下方法来生成素数:
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
However, this is comparatively much slower than my previous code, where I wasn't using the all
function, and was making the checks myself as below: 但是,这比我以前的代码要慢得多,在我以前的代码中我没有使用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
While the second one gets over within 10 seconds, the first one takes forever to complete. 当第二个在10秒内结束时,第一个要花很长时间才能完成。 Can someone help me understand why the first one starts outputting so slowly after the first 100000 numbers? 有人可以帮助我理解为什么第一个数字在第一个100000个数字之后开始如此缓慢地输出吗?
While your idea to shorten the code using that generator expression and any
is good, they are not equivalent. 当你的想法,使用发电机表达缩短了代码和any
好,他们是不等价的。 In particular, in your longer solution, you are iterating the (sorted) list of primes and break the iteration as soon as you found a prime for which p ** 2 > candidate
is true. 特别是,在较长的解决方案中,您要迭代素数的(排序的)列表,并在找到p ** 2 > candidate
为真的素数后立即中断迭代。
In your generator expression however, you try to make this check using x for p in primes if p ** 2 <= candidate
. 但是,在生成器表达式中, x for p in primes if p ** 2 <= candidate
,则尝试使用x for p in primes if p ** 2 <= candidate
进行此检查。 This is unfortunately not the same. 不幸的是,这是不一样的。 Even if that check fails, the generator will still continue to iterate over the remaining primes, performing that p ** 2
for every single prime, on every iteration of the outer while
loop. 即使检查失败,发电机仍会继续遍历剩下的素数,执行的是p ** 2
每单质,在外部的每次迭代 while
循环。
You can verify that this is the problem, if you write it a bit differently: 如果您编写的方式有所不同,则可以验证这是问题所在:
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
So now, we're using the same idea from the longer version and abort the iteration on primes
as soon as we hit a prime for which p ** 2 > candidate
is true. 因此,现在,我们在较长版本中使用相同的想法,并在达到p ** 2 > candidate
为真的primes
终止primes
的迭代。 That way, we get the speed from the longer solution back. 这样,我们可以从更长的解决方案中获得更快的速度。
we can actually use 6n +/- 1
rule for generating primes. 我们实际上可以使用6n +/- 1
规则生成素数。 for example if you want to generate primes for a given number: 例如,如果要生成给定数字的质数:
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.