Pythonのクロージャ、イテレータ、ジェネレータを使ってそれぞれフィボナッチ数を生成するコードを書いてみる。
まずはクロージャ。
Python
def fibonacci_closure():
values = []
def fibonacci():
if not values:
values.append(0)
return values[0]
elif len(values) == 1:
values.append(1)
return values[1]
else:
next_fib = sum(values)
values[0], values[1] = values[1], next_fib
return next_fib
return fibonacci
next_fibonacci = fibonacci_closure()
for i in range(17):
fib = next_fibonacci()
print fib,
結果
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
次はイテレータ。
Python
class FibonacciIterator(object):
def __init__(self):
self.values = []
def __iter__(self):
return self
def next(self):
if not self.values:
self.values.append(0)
return self.values[0]
elif len(self.values) == 1:
self.values.append(1)
return self.values[1]
else:
next_fib = sum(self.values)
self.values[0], self.values[1] = self.values[1], next_fib
return next_fib
for fib in FibonacciIterator():
if fib > 1000:
break
print fib,
結果
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
最後にジェネレータ。
Python
def fibonacci_generator():
values = [0, 1]
yield 0
yield 1
while True:
next_fib = sum(values)
values[0], values[1] = values[1], next_fib
yield next_fib
for fib in fibonacci_generator():
if fib > 1000:
break
print fib,
結果
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
ジェネレータは非常に簡潔に書けて良い。
ただし、ジェネレータをこのように書くと思わぬハマりどころがあるのでコンテナ化した方が良い。
Python
class FibonacciGenerator(object):
def __iter__(self):
values = [0, 1]
yield 0
yield 1
while True:
next_fib = sum(values)
values[0], values[1] = values[1], next_fib
yield next_fib
for fib in FibonacciGenerator():
if fib > 1000:
break
print fib,
結果
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
これについてはまた別記事で。
Enjoy!