使用生成器生成无限质数序列

时间:2018-11-08 00:14:32

标签: python generator

我正在尝试使用Eratosthenes筛子生成无限质数序列。这是代码:

def naturals()->int:
    '''Generate natural numbers indefinitely'''
    i = 1
    while True:
        yield i
        i = i+1

def primes():
    N = naturals()
    _ = next(N)#Pop out 1
    while True:
        n = next(N)
        yield n
        N = (i for i in N if i%n != 0)

但是,上面的生成器仅产生2,3,4 ...那么我到底在哪里出错了?

2 个答案:

答案 0 :(得分:1)

如果您对连续的划分检查感到满意,则可以实施更通用的版本:

  • 使用2初始化序列
  • 从3开始,仅检查奇数...
  • 如果N不能被任何现有素数整除,
  • ...将其添加到素数列表中并发出。
  • N增加2。

样式代码:

def primes():
    sofar = [2]
    n = 3
    yield 2

    while True:
        if all(n%i for i in sofar):
            sofar.append(n)
            yield n
        n += 2

这会在N = 250,000附近降低至100素/秒,并从那里继续降低。

答案 1 :(得分:1)

一次完成一个步骤:

while True:
    n = next(N)

n是2。

    yield n
    N = (i for i in N if i%n != 0)

这会将N包装在生成器中,该生成器将删除n的倍数的值。请注意,我们说的是 n 的倍数,而不是2的倍数。

在下一个循环中,我们从naturals()中抓取下一个元素,得到3,将其对n模量为2,得到1,但不为零。因此,我们将3分配给n并产生它。然后,我们将前一个N包装到另一个生成器中,该生成器的功能与前一个包装器相同,这会降低其速度,但没有其他作用。

然后,在下一个循环中,我们从naturals()中抓取下一个元素,将其对4乘以n的模数,得到1,但不为零。然后,我们再次进行模量计算,得到相同的结果。因此我们将4分配给n并产生它...