How to Resolve "RecursionError: maximum recursion depth exceeded" in Python
The RecursionError: maximum recursion depth exceeded
is a common error in Python that signals a problem with recursive function calls. It occurs when a function calls itself too many times, either directly or indirectly, exceeding Python's built-in limit for the call stack depth.
This guide explains the cause of this error and provides effective solutions, primarily focusing on ensuring a proper base case for recursion.
Understanding the Error: Infinite Recursion
Recursion is a technique where a function calls itself to solve a smaller version of the same problem. Each function call adds a new frame to the Python call stack. To prevent the stack from growing infinitely (which would consume all available memory), Python sets a limit on the maximum depth of recursion.
The RecursionError
occurs when this limit is reached, typically because:
-
Missing Base Case: The recursive function lacks a condition (a "base case") to stop calling itself.
-
Incorrect Base Case: The base case exists but is never reached due to a logical error.
Error Example:
def countdown(n):
print(n)
countdown(n - 1) # No condition to stop calling itself
# This will eventually cause the error:
# countdown(5)
# ⛔️ RecursionError: maximum recursion depth exceeded
Solution 1: Implement a Base Case (Recommended)
The fundamental solution is to ensure your recursive function has a clearly defined base case, i.e. a condition under which the function stops calling itself and returns a result (or simply returns).
def countdown_fixed(n):
if n <= 0: # Base case: Stop when n is 0 or less
print("Blast off!")
return # Exit the function
else:
print(n)
countdown_fixed(n - 1) # Recursive call with a smaller value
countdown_fixed(5)
# Output:
# 5
# 4
# 3
# 2
# 1
# Blast off!
- The
if n <= 0:
condition acts as the base case. Whenn
reaches 0, the function prints "Blast off!" andreturn
s, stopping the recursion. - Each recursive call (
countdown_fixed(n - 1)
) moves closer to the base case.
Solution 2: Increase the Recursion Limit (Use with Caution)
While possible, increasing Python's recursion limit is generally not recommended as a primary solution. It often masks an underlying problem (like an infinite recursion) rather than fixing it, and can lead to stack overflow crashes if the limit is set too high.
import sys
current_limit = sys.getrecursionlimit()
print(f"Current recursion limit: {current_limit}") # Default is often 1000
# Increase the limit (use cautiously!)
try:
new_limit = 2000
sys.setrecursionlimit(new_limit)
print(f"New recursion limit: {sys.getrecursionlimit()}")
# Now, a deeper recursion might work (but might still be flawed logic)
# def deep_recursion(n):
# if n <= 0: return
# deep_recursion(n-1)
# deep_recursion(1500) # Might work now, but could crash if limit is too high
# print("Deep recursion finished.")
except Exception as e:
print(f"Error setting recursion limit or during recursion: {e}")
finally:
# It's good practice to reset it if you changed it temporarily,
# though exiting the script usually does this.
# sys.setrecursionlimit(current_limit)
pass # Avoid resetting in simple examples
sys.getrecursionlimit()
: Retrieves the current limit.sys.setrecursionlimit(limit)
: Sets a new limit.- Use Case: This might be necessary for algorithms that are inherently deeply recursive and correctly designed with a base case, but whose depth naturally exceeds the default limit. However, first consider if an iterative solution is possible.
Setting the recursion limit too high can consume excessive memory and potentially crash your Python interpreter or even the operating system due to a stack overflow. Only increase it if you are certain your recursive logic is correct and requires more depth.
Related Cause: Infinite Loops Calling Functions
Although not technically recursion, an infinite while
loop that repeatedly calls any function (even a non-recursive one) can also eventually lead to a RecursionError
or, more likely, a MemoryError
or just hang the program, because the call stack still grows with each function call within the loop if not managed properly.
def do_something():
# This function itself isn't recursive
pass
# Infinite loop - will eventually cause issues
# while True:
# do_something()
Solution: Ensure all loops have proper termination conditions.
i = 10
while i > 0:
do_something()
i -= 1 # Move towards the termination condition
Debugging the Error
The traceback provided with the RecursionError
is crucial:
Traceback (most recent call last):
File "main.py", line X, in <module>
your_function(...)
File "main.py", line Y, in your_function
your_function(...) # Recursive call
... (many similar lines repeated) ...
File "main.py", line Y, in your_function
your_function(...)
RecursionError: maximum recursion depth exceeded
- Look at the repeated lines in the traceback. They point directly to the function (
your_function
) and the line (line Y
) where the recursive call is happening. - Examine the logic within that function. Ask yourself:
- Is there a base case?
- Is the base case condition correct?
- Does every recursive call make progress towards the base case?
Conclusion
The RecursionError: maximum recursion depth exceeded
almost always indicates infinite recursion due to a missing or incorrect base case in your recursive function.
- The primary solution is to implement or fix the base case to ensure the recursion terminates.
- While increasing the recursion limit with
sys.setrecursionlimit()
is possible, it should be used with extreme caution and only when you are certain the underlying recursive algorithm is correct but naturally requires deep nesting. - Analyze the traceback carefully to pinpoint the source of the infinite recursion.