繁体   English   中英

Python中素数的生成器

[英]generator of prime numbers in Python

我尝试使用Eratosthenes的steve在Python中创建所有素数的流。 但是,我收到一个错误。

这是我尝试过的:

def genPrimes0(N):
    if (isPrime(N)):
        yield [N]
        filter(lambda x: N%x[0] == 0, genPrimes0(N+1))
    else:
        genPrimes0(N+1)


P = genPrimes0(2)

这是控制台:

>>> ================================ RESTART ================================
>>> 
>>> P.next()
[2]
>>> P.next()

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    P.next()
StopIteration
>>> 

任何想法 ?

编辑:

我想要递归。 我想用LAZY评估做一个实验。 特别是对这个问题不感兴趣,但关于懒惰的评估 - 我完全随机地选择了这个问题来进行实验。

我正在使用带有Idle的Python 2.7,但这并不重要。 了解会发生什么很重要。

我觉得你在当前的发电机上做得太辛苦了。 你可以减少工作量(例如拥有一个isPrime oracle)并让算法做它的事情:

def primes(n=2): # don't provide a different n value, or you will get odd results
    yield n
    yield from filter(lambda x: x % n, primes(n+1))

这使用了一些Python 3.3特定的语法( yield from ),但是你可以为早期版本做一个等效的生成器,只需使它成为过滤器结果的显式循环。 @ icktoofay的答案显示了这种循环(他还指出filter只是Python 3中的一个生成器,所以如果你使用的是Python 2,请使用itertools.ifilter )。

示例输出:

>>> for p in primes():
    print(p)
    if p > 100:
        break


2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
101

您不需要递归进行延迟评估,您可以使用itertools中的函数来懒惰地计算素数。

import itertools    

def primes():
    numbers = itertools.count(2)
    while True:
        p = numbers.next()
        numbers = itertools.ifilter(lambda x, p=p: x%p, numbers)
        yield p

print list(itertools.islice(primes(), 100))

这不是Eratosthenes,但som非尾递归函数只是填充堆栈。 如果你有isPrime函数,你应该写

def gen_primes(start):
   return itertools.filter(isPrime , itertools.count(start) )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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