イテレータバージョン
<< 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 >>
<< 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()
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