我试图让下面的生成器能够设置返回数字的上限。在Python中为无限生成器设置限制
调用list(it.takewhile(lambda x: x < 100, get_primes()))
收益100如预期,但list(get_primes(100))
(应该以同样的方式返回相同的列表)下的所有质数的列表只是一个空列表返回。
显然,我可以在for
循环中包含一个if n and candidate>=n: break
,但我最感兴趣的是为什么if n: return
构造不能像我期待的那样工作。它不应该只是返回上面工作的相同的takewhile
迭代器吗?我在这里忽略了什么?
import itertools as it
def get_primes(n=None):
"""
Generates primes to a max of n.
>>> list(get_primes(100))
[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]
"""
if n:
return it.takewhile(lambda x: x < n, get_primes())
composites = {}
yield 2
for candidate in it.count(3, 2):
prime_factor = composites.pop(candidate, None)
if prime_factor is None:
yield candidate
composites[candidate**2] = candidate
else:
composite = candidate + 2*prime_factor
while composite in composites:
composite += 2*prime_factor
composites[composite] = prime_factor
尽管用'yield'替换'return'并不会产生预期的行为(生成器将产生另一个生成器作为第一个值)。 – isedev 2014-10-05 19:44:17
@isedev:'yield from'将直接替代'return'(一个普通的“yield”,当然不会)。 – NPE 2014-10-05 19:46:21
当然,如果你可以使用从'yield'来商定。否则,实际的生成器将需要被封装在一个嵌套函数中,这样外函数在两种情况下都可以返回。 – isedev 2014-10-05 19:46:32