我正在尝试使下面的生成器能够设置返回数字的上限。
调用list(it.takewhile(lambda x: x < 100, get_primes()))
会按预期返回100以下所有素数的列表,但list(get_primes(100))
(应该以相同的方式返回相同的列表)只返回一个空列表。
显然,我可以在if n and candidate>=n: break
循环中包含for
,但我最感兴趣的是为什么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
答案 0 :(得分:3)
下面:
return it.takewhile(lambda x: x < n, get_primes())
由于这是一个生成器,因此需要yield
这些值而不是return
它们。根据您的Python版本,您可以使用yield from
语法。
以下内容可能有助于作为背景阅读:Return in generator together with yield in Python 3.3
答案 1 :(得分:2)
问题在于
行return it.takewhile(lambda x: x < n, get_primes())
由于它是一个生成器,返回一些东西会停止执行,并引发StopIteration()。您需要返回生成器
中的值#return all the values from generator
for a in it.takewhile(lambda x: x < n, get_primes())
yield a
return