How Recursion Works
When a function calls itself, a new frame is added to the call stack. When the base case is reached, the frames unwind and return values back up the chain.
def countdown(n):
if n <= 0: # Base case - MUST exist to prevent infinite loop
print("Done!")
return
print(n)
countdown(n - 1) # Recursive case - calls itself with smaller n
countdown(5)
Classic Example β Factorial
n! (n factorial) = n Γ (n-1) Γ (n-2) Γ ... Γ 1. This is the quintessential recursion example.
def factorial(n):
if n == 0 or n == 1: # Base case
return 1
return n * factorial(n - 1) # Recursive case
print(factorial(5)) # 120 (5Γ4Γ3Γ2Γ1)
print(factorial(10)) # 3628800
Fibonacci Sequence
Fibonacci: each number is the sum of the two preceding ones. 0, 1, 1, 2, 3, 5, 8, 13...
def fibonacci(n):
if n <= 1: # Base case
return n
return fibonacci(n-1) + fibonacci(n-2) # Recursive
for i in range(8):
print(fibonacci(i), end=" ")
Naive Fibonacci recursion is exponentially slow (O(2^n)). Use memoization (@functools.lru_cache) for performance.
Recursion vs Iteration
Recursion is elegant but not always the best choice. Python has a default recursion limit of 1000 calls (sys.setrecursionlimit()).
# Recursive factorial
def factorial_recursive(n):
return 1 if n <= 1 else n * factorial_recursive(n - 1)
# Iterative factorial (usually preferred in Python)
def factorial_iterative(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
print(factorial_recursive(10)) # 3628800
print(factorial_iterative(10)) # 3628800 - same result