简体   繁体   English

python中的质数生成代码

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM