Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallIn Python, recursion means a function calls itself to solve a smaller or simpler version of a problem. A sound recursive function has a base case that stops the calls and a recursive step that moves each call toward that case. Those two parts make recursion useful—and help prevent a runaway chain of calls.
What recursion means in Python
When a function calls itself, Python starts another function call with its own local symbol table. That call has its own local variables and runs independently while the earlier call waits for a result. Once the new call returns, execution resumes in the waiting call.
As an Amazon Associate I earn from qualifying purchases.
This creates a chain of active calls. Recursion fits problems that can be expressed as smaller instances of the same problem, such as traversing nested structures or calculating a value from a smaller input. The Python tutorial explains both function-call behavior and recursive functions in its control-flow tutorial.
Recommended Free Tools
How to write a recursive function
Build every recursive function around two parts:
- Base case: the condition under which the function returns without calling itself again.
- Recursive step: the part that calls the function with an input closer to the base case.
If the recursive step does not make progress toward the stopping condition, calls can continue until Python raises RecursionError.
#1 Best Overall
Example: factorial with a base case
For a nonnegative integer n, factorial is the product of the integers from 1 through n; by convention, 0! is 1. This implementation expects a nonnegative integer:
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
Identify the two parts
- Base case: when
n == 0, return1without another call. - Recursive step: otherwise, multiply
nby the factorial ofn - 1. Subtracting 1 moves the input toward zero.
Trace factorial(4)
The calls proceed as 4 * factorial(3), 3 * factorial(2), 2 * factorial(1), and 1 * factorial(0). The base case returns 1; as each call finishes, its waiting multiplication resolves. The final result is 24.
Rank #2
Recursion, repeated work, and memoization
Recursion describes how a solution is structured; it does not automatically make the computation efficient. A naïve recursive Fibonacci function, for example, recalculates the same subproblems many times. When calls repeat with the same arguments, caching can avoid some of that repeated work.
Python’s functools.cache, available from Python 3.9, stores results for arguments that can be used as dictionary keys. Here is the factorial example with caching:
from functools import cache
@cache
def factorial(n):
return n * factorial(n - 1) if n else 1
The functools documentation describes cache as an unbounded cache equivalent to lru_cache(maxsize=None). Its example reports that the first call to factorial(10) makes 11 calls, while later calls using cached arguments can return without new calls. This is the documentation’s example, not a performance guarantee for other workloads.
Caching helps when subproblems repeat, but it does not shorten a single chain of nested calls. An unbounded cache also retains entries, so a workload with many distinct arguments can use more memory. Consider both call depth and retained results when choosing an approach.
Recursion or a loop?
Neither approach is always better. Choose based on the structure of the problem and the behavior of the implementation:
| Consideration | Recursion | Iteration |
|---|---|---|
| Call depth | Each nested call adds to the active call chain; a long chain can reach Python’s recursion limit. | A loop can handle a long linear sequence without adding one function call per item. |
| Repeated subproblems | Repeated calls can redo work; memoization may help when arguments repeat and are cacheable. | A loop can carry forward results directly when the calculation has a simple sequential structure. |
| Memory | Active calls use call frames; caching retains results as well. | A loop often avoids a deep call chain, though its own data structures still use memory. |
| Clarity | Can mirror nested data or a problem naturally defined in terms of smaller instances. | Can be easier to trace for a long, straightforward sequence. |
Python’s tutorial demonstrates Fibonacci generation with a while loop. For a deep linear process, an iterative design is often preferable; for nested or divide-and-conquer structure, recursion may express the logic more directly. These are design considerations, not a promise that one version will run faster in every case.
Best Value
Why Python raises RecursionError
RecursionError is a subclass of RuntimeError. Python raises it when the interpreter detects that the maximum recursion depth has been exceeded, as documented under built-in exceptions. Common causes include a missing base case, a recursive step that fails to approach it, or a valid but unusually deep chain of calls.
Check the function’s stopping condition and trace whether each recursive argument moves toward it. If the function is correct but the required chain is very deep, consider whether a loop or a redesigned algorithm can avoid that depth.
Checking and changing the recursion limit
sys.getrecursionlimit() returns the interpreter’s current recursion limit. Python uses a limit to help prevent infinite recursion from overflowing the C stack. The sys documentation also describes sys.setrecursionlimit(), but warns that the highest safe value depends on the platform and that setting the limit too high can crash Python.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesimport sys
print(sys.getrecursionlimit())
Changing the limit should not be the routine response to RecursionError. First verify that the recursive function has a reachable base case and makes progress. For work that requires a very deep linear chain, prefer an iterative solution or another redesign; raise the limit only when you understand the platform and stack-safety implications.
Further reading
For a book focused specifically on recursive programming, Al Sweigart’s The Recursive Book of Recursion uses Python and JavaScript examples. Publisher information is available from No Starch Press and Penguin Random House.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




