22010


* * *

Python初心者です。以下のようなフィボナッチ数列を生成するコードについて質問があります。

[code]

    def fastFib(n, memo = {}):
        if n == 0 or n == 1:
            return 1
        try:
            return memo[n]
        except KeyError:
            result = fastFib(n-1, memo) + fastFib(n-2, memo)
            memo[n] = result
            return result
    
[/code]

これは、memoに計算済みのフィボナッチ数列の値を保存して、再帰的に呼び出すことで、重複する計算を回避することを意図したものです。コードは、"Python言語によるプログラミングイントロダクション"
p. 281 からコメントアウト以外の部分を引用しました。

この際、全ての再帰呼び出し関数が持つ名前テーブルにmemoが存在する必要があると思うのですが、それはmemoの初期化を行っているのが関数宣言内であるからでしょうか？

名前テーブルの扱いが分からないもので、より詳しく知ることのできるキーワードやドキュメントを教えていただければ幸いです。


CC BY-SA 3.0
2016-02-12T12:09:28.387
22009
2016-02-16T23:08:13.220
14383
question
python
pythonにおける名前空間の扱いについて


これは、引数のデフォルト値がどういう挙動をするかという問題ですね。

Python 言語定義の [7.6
関数定義](http://docs.python.jp/2.7/reference/compound_stmts.html#function-
definitions)のところを読むと

> ** デフォルトパラメタ値は関数定義を実行する際に値評価されます。 ** これは、デフォルトパラメタの式は関数を定義するときにただ一度だけ評価され、同じ
> ” 計算済みの ”
> 値が全ての呼び出しで使われることを意味します。デフォルトパラメタ値がリストや辞書のような変更可能なオブジェクトである場合、この使用を理解しておくことは特に重要です
> : 関数でこのオブジェクトを ( 例えばリストに要素を追加して ) 変更すると、実際のデフォルト値が変更されてしまいます。

とあります。つまり、今回の場合は memo のデフォルトの辞書は、ただ一つだけ生成され、fastFib が呼び出されるたびに同じ物が使いまわされるわけです。

`def fastFib(n, memo = {}):` のところだけ見ていると、呼び出されるたびに空の辞書が作られるような気になってしまいますが
(私もむかし、勘違いしてました)、実際は最初に一つだけなので注意が必要です。


CC BY-SA 3.0
2016-02-12T12:59:33.153
22010
2016-02-12T13:07:20.703
2016-02-12T13:07:20.703
3605
3605
22009
answer


Hidekiさんと同じ内容ですがもう少しかみ砕いた説明です  
[デフォルトの引数値](http://docs.python.jp/3.5/tutorial/controlflow.html#default-
argument-values)

「 **重要な警告** 」となっている箇所を読んでみてください。


CC BY-SA 3.0
2016-02-16T23:08:13.220
22183
2016-02-16T23:08:13.220
13838
22009
answer