Recursive Functions
Learn recursion by creating functions that call themselves.
Recursion is when a function calls itself to solve smaller instances of the same problem. It is powerful for problems that can be broken down into similar subproblems.
📚 Concepts & Theory
Recursion is a programming technique where a function calls itself to solve a problem by breaking it into smaller, similar subproblems.
Basic Recursion Pattern:
def recursive_function(parameter):
# Base case: stop condition
if base_condition:
return base_value
# Recursive case: call itself with smaller problem
return recursive_function(smaller_parameter)
Classic Example - Factorial:
def factorial(n):
# Base case
if n == 0 or n == 1:
return 1
# Recursive case
return n * factorial(n - 1)
# factorial(5) = 5 * factorial(4)
# = 5 * 4 * factorial(3)
# = 5 * 4 * 3 * factorial(2)
# = 5 * 4 * 3 * 2 * factorial(1)
# = 5 * 4 * 3 * 2 * 1
# = 120
Essential Components:
1. Base Case (Stopping Condition):
Prevents infinite recursion, provides final answer:
if n == 0:
return 1 # Must return, not recurse
2. Recursive Case:
Calls itself with a simpler/smaller problem:
return n * factorial(n - 1) # n-1 is smaller
3. Progress Toward Base Case:
Each call must get closer to the base case:
factorial(5) → factorial(4) → factorial(3) → ... → factorial(1)
More Examples:
Countdown:
def countdown(n):
if n <= 0:
print("Done!")
return
print(n)
countdown(n - 1)
countdown(5) # Prints 5, 4, 3, 2, 1, Done!
Sum of List:
def sum_list(numbers):
if not numbers: # Empty list
return 0
return numbers[0] + sum_list(numbers[1:])
sum_list([1, 2, 3, 4, 5]) # 15
Fibonacci:
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# fibonacci(5) = 5
String Reversal:
def reverse(text):
if len(text) <= 1:
return text
return reverse(text[1:]) + text[0]
reverse("hello") # "olleh"
Recursion vs Iteration:
Recursive:
def sum_recursive(n):
if n == 0:
return 0
return n + sum_recursive(n - 1)
Iterative:
def sum_iterative(n):
total = 0
for i in range(n + 1):
total += i
return total
When to Use Recursion:
✅ Tree/graph traversal
✅ Divide and conquer algorithms
✅ Problems with recursive structure (factorials, Fibonacci)
✅ Backtracking problems
When NOT to Use:
❌ Simple iterations (use loops)
❌ Performance critical code (recursion has overhead)
❌ Very deep recursion (stack overflow risk)
Python Recursion Limit:
import sys
print(sys.getrecursionlimit()) # Usually 1000
# Can increase (carefully!)
sys.setrecursionlimit(2000)
Common Pitfalls:
# ❌ No base case - infinite recursion!
def bad_function(n):
return bad_function(n - 1)
# ❌ Never reaches base case
def bad_countdown(n):
if n == 0:
return
print(n)
bad_countdown(n + 1) # Gets larger, not smaller!
# ✅ Proper recursion
def good_countdown(n):
if n == 0:
return
print(n)
good_countdown(n - 1) # Gets smaller
🎯 Your Challenge
Create a recursive function countdown(n) that prints numbers from n down to 1, then prints "Blast off!"
📝 Starter Code
def countdown(n):
pass
- Start with the base case: if n <= 0
- In base case, print Blast off! and return
- In recursive case, print the current number
- Then call countdown(n - 1) for the next smaller number
- Make sure each call gets closer to the base case
Solution
def countdown(n):
if n <= 0:
print("Blast off!")
return
print(n)
countdown(n - 1)
Explanation
This recursive function demonstrates the classic recursion pattern. The base case (n <= 0) stops the recursion by printing "Blast off!" and returning without further calls. The recursive case prints the current number n, then calls countdown(n - 1) with a smaller value, progressing toward the base case. When countdown(5) is called, it prints 5, calls countdown(4), which prints 4, calls countdown(3), and so on until countdown(0) triggers the base case. The recursion "unwinds" back up the call stack. This is cleaner than iteration for problems with natural recursive structure.
⚠️ Common Mistakes to Avoid
- Forgetting the base case (causes infinite recursion/stack overflow)
- Base case that never triggers (wrong condition)
- Not making progress toward base case (n+1 instead of n-1)
- Forgetting to return in base case
- Printing in wrong order (before vs after recursive call matters)