Python で「RecursionError: maximum recursion depth exceeded」が解決できない
再帰呼び出しが Python の既定上限(およそ1000)を超えたためです。
多くは終了条件のミスによる無限再帰なので、まずベースケースを確認し、必要なら反復処理へ書き換えます。
公開: 更新:
要約
RecursionError: maximum recursion depth exceeded は、関数の再帰呼び出しの深さが Python の既定上限(既定およそ 1000)を超えると送出されます。
大半は終了条件のバグによる無限再帰なので、上限を上げる前にベースケースを疑うのが鉄則です。
よくある原因
- ベースケースの誤り: 再帰を止める条件が一度も真にならず、関数が自分を呼び続ける。
- 正当に深い再帰: 木やグラフの探索など、データが大きく既定上限を正当に超えるケース。
- 想定外の自己呼び出し:
__getattr__や__repr__の中でその属性を再参照し、無限ループになる。
解決策
1. まずベースケースを点検する
無限再帰は上限を上げても解決しません。
終了条件が必ず到達するか確認します。
def factorial(n):
if n <= 1: # ← このベースケースが正しいか
return 1
return n * factorial(n - 1)引数が単調に終了条件へ近づいているかを必ず確認してください。
2. 必要なときだけ上限を引き上げる
正当に深い再帰なら上限を調整します。
import sys
sys.setrecursionlimit(10000)sys.setrecursionlimit は公式ドキュメント(新しいタブで開く)記載の正式 API ですが、上げ過ぎるとインタプリタがクラッシュする可能性があるため必要最小限にとどめます。
3. 反復処理へ書き換える
最も安全なのは再帰をループ+明示的スタックに変換することです。
def factorial_iter(n):
result = 1
for i in range(2, n + 1):
result *= i
return result深い探索はスタックを使った反復に置き換えると、データサイズに依存せず安定します。
実行例
実際に上記の手順を python:3.12 環境で走らせると、ベースケースを持たない countdown 関数がおよそ 1000 呼び出し後に RecursionError を送出して終了コード 1 で終了し、正しいベースケースの追加およびループへの書き換えではいずれも期待どおり factorial(5) = 120 が返された。
$ python bad.py
Traceback (most recent call last):
File "/tmp/tmp.SbtF2oN4nS/bad.py", line 5, in <module>
countdown(5)
File "/tmp/tmp.SbtF2oN4nS/bad.py", line 3, in countdown
return countdown(n - 1)
^^^^^^^^^^^^^^^^
File "/tmp/tmp.SbtF2oN4nS/bad.py", line 3, in countdown
return countdown(n - 1)
^^^^^^^^^^^^^^^^
File "/tmp/tmp.SbtF2oN4nS/bad.py", line 3, in countdown
return countdown(n - 1)
^^^^^^^^^^^^^^^^
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
終了コード: 1$ python solve_base_case.py
factorial(5) = 120$ python solve_iter.py
factorial_iter(5) = 120$ python -c "import sys; print('recursionlimit =', sys.getrecursionlimit())"
recursionlimit = 1000— 2026-08-02 時点の出力
検証環境
- 検証日
- 実行環境
python:3.12
この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。