繁体   English   中英

斐波那契生成器迭代器和无限生成器

[英]Fibonacci generator iterator and infinite generators

我有这个 FibIter 生成器。 我正在尝试使用生成器表达式创建第二个。

def FibIter():
    yield 0
    yield 1
    x = 0
    y = 1
    while True:
        result = x + y
        x, y = y, result
        yield result

fibiter = FibIter()
fibiter_in_range = (x for i, x in enumerate(fibiter) if 100000 < i <= 100020)

现在,如果我在下面运行代码,什么都不会发生。

print(list(fibiter_in_range))

如果我运行低于数字的代码,则会打印出来,但for循环不会结束。

for x in fibiter_in_range:
    print(x)

我想我可以遍历fibiter_in_range直到使用所有元素。

我对发电机有什么不明白的地方? 如何优雅地创建具有 n 在 100000-100020 范围内的斐波那契数的迭代器?

问题是您的生成器永远不会结束,并且您的生成器表达式会不断地从中获取输出,即使在i达到其上限之后也是如此。

做你想做的一个简单的方法是使用itertools.islice

from itertools import islice

def FibIter():
    yield 0
    yield 1
    x = 0
    y = 1
    while True:
        result = x + y
        x, y = y, result
        yield result

fibiter = FibIter()
fibiter_in_range = islice(fibiter, 10, 15)
print(list(fibiter_in_range))
# [55, 89, 144, 233, 377]

Python 不够聪明,无法知道if 100000 < i <= 100020将导致新生成器在100020之后停止产生。 据它所知,以后可能会有一些元素满足条件,所以它需要不断拉动,看看最终是否满足它。

您可以使用dropwhiletakewhile来过滤:

from itertools import takewhile, dropwhile

...


fibiter = FibIter()
fibiter_in_range = takewhile(lambda n: n <= 10002000,
                             dropwhile(lambda n: n < 100000, fibiter))

>>> list(fibiter_in_range)
[121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465]

但是,此过滤器基于数字的值,而不是它们在生成器中的索引,因为您写道您想要“优雅地创建具有 n 在 100000-100020 范围内的斐波那契数的迭代器?”。 为了示例,我增加了上限,因为它没有找到任何其他元素。

暂无
暂无

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

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