Pythonのクロージャについて調べていたときに、下記の記事を発見した。
この記事の中の以下のコードの挙動がうまく理解できなかったので、色々調べてみた。
def fibonacci_func(): """フィボナッチ数列を返す関数を返す メモイズ機能つき""" table = {} # 計算済みのフィボナッチ数列を格納するテーブル def fibonacci(n): # 計算したことのある数値についてはテーブルを参照して返す if n in table: return table[n] # 計算したことのない数値についてはフィボナッチ数列の定義どおり計算 if n < 2: return 1 table[n] = fibonacci(n - 1) + fibonacci(n - 2) return table[n] return fibonacci f = fibonacci_func() print(f(30))
結論としては、メソッドfibonacci内で使い回すtableをfibonacciの外で定義しているということ。 したがって、下記のfibonacci2と挙動は同じ
def fibonacci2(n, table={}): # 計算したことのある数値についてはテーブルを参照して返す if n in table: return table[n] # 計算したことのない数値についてはフィボナッチ数列の定義どおり計算 if n < 2: return 1 table[n] = fibonacci2(n - 1) + fibonacci2(n - 2) return table[n]
ちなみに、このメモイズ機能を使うことで自分のPCの場合、30番目のフィボナッチ数列の値を計算する時間が 300msから10msに短縮された。