クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

自分を呼ぶ関数:再帰

このレッスンのあとで: 自分自身を呼ぶ再帰の関数を、基本ケースを付けて書ける。

45分のレッスンコマンド2件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

入れ子の人形を開ける

入れ子になった人形は、開けると、中に少し小さい人形が入っています。それも開けると、さらに小さい人形です。

いちばん小さい人形が出たら、もう開けません。関数が自分自身を呼ぶ再帰も、これとそっくりな仕組みです。

このレッスンのゴール

メモ

自分自身を呼ぶ再帰の関数を、基本ケースを付けて書ける。

重要な言葉

ことばいみ
再帰関数が、自分自身を呼ぶこと
基本ケース自分を呼ばずに、答えを返して止まる場合
再帰ケース少し小さい問題で、自分を呼ぶ場合
コールスタック呼び出し中の関数を、積み重ねて覚えておく場所
スタックオーバーフロー呼び出しが深すぎて、覚える場所が足りなくなること

学生が入力するセルは、このプレビューでは空白です。

再帰には二つの場合がある

数を数えて 3、2、1、0 と言う手順を考えます。「0 なら言って止まる。そうでなければ言って、一つ小さい数でもう一度やる」と書けます。

止まる場合が基本ケース、もう一度やる場合が再帰ケースです。基本ケースがないと、永遠に止まりません。

カウントダウンの再帰

コード: python
def countdown(n):
    # まず今の数を言う
    print(n)
    # 基本ケース:0 なら何もせず、ここで止まる
    if n > 0:
        # 再帰ケース:一つ小さい数で、自分を呼ぶ
        countdown(n - 1)


countdown(3)
# 3 を 5 に変えて、何が出るか確かめましょう

階乗を再帰で書く

5の階乗は、5 × 4 × 3 × 2 × 1 で、120です。これは「5 × 4の階乗」とも言えます。

0の階乗は1と決めます。これが基本ケースです。n が0でなければ、n * fact(n - 1) を返します。

5の階乗を再帰で計算する

コマンド
docker exec jupyter python3 -c 'exec("def fact(n):\n    if n == 0:\n        return 1\n    return n * fact(n - 1)\nprint(fact(5))")'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

呼び出しはコールスタックに積まれる

fact(3) は、fact(2) の答えが出るまで待ちます。fact(2) は fact(1) を待ちます。待っている呼び出しは、コールスタックに積み重なります。

基本ケースに着くと、答えが一番上から順に返っていき、待っていた掛け算が終わります。

例:fact(3) の呼び出し

段階呼び出し返す値
積むfact(3) が fact(2) を呼ぶまだ待つ
積むfact(2) が fact(1) を呼ぶまだ待つ
積むfact(1) が fact(0) を呼ぶまだ待つ
底fact(0)1
戻るfact(1) は 1 × 11
戻るfact(2) は 2 × 12
戻るfact(3) は 3 × 26

学生が入力するセルは、このプレビューでは空白です。

基本ケースがないと止まらない

基本ケースがない再帰は、呼び出しを積み続けます。積める数には限りがあり、超えるとエラーになって止まります。

次の実行で、Python が許す呼び出しの深さを見ます。見るだけで、何も壊れません。

許される深さを見る

コマンド
docker exec jupyter python3 -c 'print(__import__("sys").getrecursionlimit())'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

基本ケースを書き忘れたり、問題が小さくならない呼び方をしたりしがちです。たとえば fact(n) の中で fact(n) を呼ぶと、永遠に終わりません。自分を呼ぶときは、必ず基本ケースへ近づく値で呼びます。

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。