无限收益问题

时间:2010-11-01 17:05:46

标签: python generator

这是我的简单代码

class Fibonacci:
    @staticmethod
    def series():
        fprev = 1
        fnext = 1
        yield fnext
        while True:
            yield fnext
            fprev,fnext = fnext,fprev+fnext

under10 = (i for i in Fibonacci.series() if i<10)
for i in under10 :
    print i

这是非常明显的,但是......为什么解释器正在执行块

while True:
                yield fnext
                fprev,fnext = fnext,fprev+fnext

永远? 我在生成器中指定,我只想要元素&lt; 10

under10 = (i for i in Fibonacci.series() if i<10)
恕我直言,这有点误会 没有重写“系列”的任何方法来阻止无限执行?

3 个答案:

答案 0 :(得分:16)

口译员应该如何知道所有未来的号码都将是&lt; 10?它必须知道(某种程度上)它正在制造Fibonacci系列,否则就必须检查整个系列。

它不能做第一个,所以它做第二个。

您可以使用itertools.takewhile

解决此问题
import itertools

under10 = itertools.takewhile(lambda n: n < 10, Fibonacci.series())

答案 1 :(得分:0)

under10 = (i for i in Fibonacci.series() if i<10) 

继续前进,它不会产生大于10的值。没有任何指示for循环停止。

你可能会有更好的运气,比如:

for i in Fibonacci.series():
    if i > 10:
        break
    #do your appends and such here

编辑:

我更喜欢Konrad的itertools例子,我总是忘记了itertools

答案 2 :(得分:0)

无限循环不是while True:方法中Fibonacci.series()的结果。它是由under10 = (i for i in Fibonacci.series() if i<10)生成器引起的,它只是继续前进,因为它没有意识到产生的值永远不会变小。这是[另一种]修复它的方法并同时概括它 - 无需重新编写series() - 使用itertools.takewhile()迭代器:

import itertools
fibos_under = lambda N: itertools.takewhile(lambda f: f < N, Fibonacci.series())

for i in fibos_under(10):
    print i

BTW:您可以稍微简化Fibonacci.series()方法,方法是将其更改为生成相同值的方法:

class Fibonacci:
    @staticmethod
    def series():
        fprev,fnext = 0,1
        while True:
            yield fnext
            fprev,fnext = fnext,fprev+fnext