簡體   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