LoginSignup
12
11

More than 5 years have passed since last update.

Pythonのクロージャ、イテレータ、ジェネレータでフィボナッチ数を生成する

Last updated at Posted at 2016-11-07

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!

12
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11