return
声明
この問題は、私が最初に再帰を学び始めたとき、実際に理解するのにかなりの時間を要しました。
Python の関数/メソッドを扱う際に留意すべきことの 1 つは、それらが何であっても常に値であるということです。 return
したがって、関数/メソッドの本体でステートメントを宣言するのを忘れるとreturn
、Python が代わりにそれを処理return None
し、最後に実行します。
これが意味することは、関数の本体を台無しにして を置き忘れreturn
たり省略したりすると、予想される戻り値の代わりに が出力されるということprint type(messed_up_function())
ですNoneType
。
再帰修正
それを念頭に置いて、再帰を扱うときは、最初に帰納的なケース以外に基本的なケースがあることを確認してください。つまり、無限再帰ループを防ぎます。
次に、両方のケースで戻っていることを確認してください。つまり、次のようになります。
def recur(val):
"""
takes a string
returns it back-to-front
"""
assert type(val) == str
# the base case
if len(val) == 1:
return val
# the inductive case
else:
return val[-1] + recur(val[:-1]) # reverses a string char by char
したがって、これは常にreturn
s であり、100% の無限再帰証明です。これは、有効な基本ケースと帰納ステップごとに減分された長さがあるためです。
再帰関数をデバッグする Stack Viewer
recur('big')
基本ケースの開始時に を追加して実行するassert False
場合、次のスタック構造になります。
そこから、各再帰ステップで、val
この関数の唯一のパラメーターである が、ヒットするまでどんどん小さくなりlen(val) == 1
、最終的な戻り値、この場合は に到達することがわかりますassert False
。したがって、これは再帰関数/メソッドをデバッグするための便利な方法です。IDLEではDebug > Stack Viewer
、シェルで呼び出して、このようなビューにアクセスできます。