【问题标题】:Fibonacci generator iterator and infinite generatorsFibonacci 生成器迭代器和无限生成器
【发布时间】:2021-04-03 17:58:04
【问题描述】:

我有这个 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 的斐波那契数的迭代器?

【问题讨论】:

    标签: python iterator generator


    【解决方案1】:

    问题是你的生成器永远不会结束,你的生成器表达式不断地从它那里得到输出,即使在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]
    

    【讨论】:

      【解决方案2】:

      Python 不够聪明,无法知道if 100000 &lt; i &lt;= 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 范围内的斐波那契数的迭代器?”。为了示例,我增加了上限,因为它没有找到任何其他元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-16
        • 1970-01-01
        • 2018-11-01
        • 1970-01-01
        • 2016-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多