python中的素数生成代码

时间:2014-07-27 12:55:25

标签: python python-2.7 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

然而,这比我以前的代码慢得多,我之前没有使用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数字后第一个开始输出的速度如此之慢?

2 个答案:

答案 0 :(得分:4)

虽然您想要使用该生成器表达式缩短代码并且any是好的,但它们并不等同。特别是,在较长的解决方案中,只要找到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

所以现在,我们在较长版本中使用相同的想法,并在我们点击primes为真的素数时立即中止p ** 2 > candidate上的迭代。这样,我们就可以从更长的解决方案中获得速度。

答案 1 :(得分:0)

我们实际上可以使用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