有人可以帮助我确定我编写的素数生成器函数中的错误吗

时间:2018-10-27 19:09:11

标签: python generator

有人可以帮我为什么在列出前25个素数时在生成器中得到某些数字,例如“ 27”和“ 35”吗?我知道有更有效的方法,例如Erathosthenes的Sieve,但我担心此代码中的某些错误。谢谢!

def next_prime():
    num = 2
    while True:
        for i in range(1, num+1):
            if (i != 1) and (num % i == 0):
                # print(num, " is not prime")
                num += 1
        yield num
        num += 1

primes = next_prime()
[print(next(primes)) for i in range(25)]

下面的输出-突出显示了一些复合数字

3 5 7 11 13 17 19 23 27 29 31 35 37 41 43 47 53 59 61 67 71 73 79 83 87

1 个答案:

答案 0 :(得分:1)

您在num循环中递增 for,但是您不能简单地这样做,因为从那时起i不是 重置为1,因此您错过了某些检查。

因此,您应该break,然后递增num,然后让循环检查下一个数字。因此,我们可以使用for-else仅在循环成功(即未达到break语句)的情况下产生一个数字。

现在将出现的另一个问题是, no 数字不再是质数。这是因为您的range(1, num+1) 包括 num,并且数字始终可以自己被分割。因此,范围应介于1(或更好的2)和num(不包括)之间:

def next_prime():
    num = 2
    while True:
        for i in range(2, num):
            if num % i == 0:
                break
        else:
            yield num
        num += 1

但是,以上不是非常有效。我们可以使这种方式更快。例如,除两个以外的所有偶数都不是质数,因此我们可以将其重写为:

def next_prime():
    yield 2
    num = 3
    while True:
        for i in range(2, num):
            if not num % i:
                break
        else:
            yield num
        num += 2

我们进一步只需要对数字n进行√n检验,因为如果n可被数字a除以a大于平方根n中的数字,则存在一个小于平方根的数字b = n / a

from math import sqrt, ceil

def next_prime():
    yield 2
    num = 3
    while True:
        for i in range(3, ceil(sqrt(num))+1, 2):
            if not num % i:
                break
        else:
            yield num
        num += 2