[python] ジェネレータとイテレータでフィボナッチ

イテレータバージョン
<< fib_iter.py >>
class Fib(object):
    def __init__(self, n): 
        self.x_2, self.x_1 = 0, 1
        self._i = 0 
        self._max = n 
    def __iter__(self):
        return self
    def next(self):
        x_2 = self.x_2
        if self._i >= self._max:
            self._i =0
            raise StopIteration
        self.x_2, self.x_1 = self.x_1, self.x_1+self.x_2
        self._i += 1
        return x_2
if __name__ == "__main__": 
    f = Fib(40)                                
    for n in f:
        print n

ジェネレータバージョン
<< fib_gen.py >>
def fib():
    x2, x1 = 0, 1
    while True:
        yield x2
        x2, x1 = x1, x2 + x1
if __name__ == "__main__":
    f = fib()
    for x in xrange(40):
        print f.next()




1 件のコメント:

  1. itertoolsのisliceを使うと、printのループがもうちょっと簡潔に書けるね。

    from itertools import islice

    if __name__ == "__main__":
        for x in islice(fib(), 40):
            print x

    ジェネレータが無限リストを生成するか、個数を引数として受け取るかは悩むところだけど、両方サポートしてしまうのはどうでしょう。

    from itertools import repeat

    def fib(n = None):
        x2, x1 = 0, 1
        for n in repeat(1) if n is None else repeat(1, n):
            yield x2
            x2, x1 = x1, x2 + x1

    返信削除