Recursion vs Iteration
- Recursion is natural for tree traversal and divide-and-conquer — the code mirrors the problem structure.
- Python's default recursion limit is 1000 frames — deep recursion causes RecursionError.
- Convert recursive solutions to iterative by using an explicit stack.
Recursion is elegant for naturally recursive problems (trees, divide and conquer) but risks stack overflow for deep calls. Iteration is safer for sequential processing and typically faster due to lower overhead. Python's default recursion limit is 1000 frames. Convert recursive solutions to iterative by using an explicit stack.
Fibonacci — Recursion vs Iteration vs Memoization
import sys import time # Naive recursion — O(2^n) time, catastrophic def fib_recursive(n): if n <= 1: return n return fib_recursive(n - 1) + fib_recursive(n - 2) # Iterative — O(n) time, O(1) space def fib_iterative(n): if n <= 1: return n a, b = 0, 1 for _ in range(2, n + 1): a, b = b, a + b return b # Memoized recursion — O(n) time, O(n) space from functools import lru_cache @lru_cache(maxsize=None) def fib_memo(n): if n <= 1: return n return fib_memo(n - 1) + fib_memo(n - 2) print(fib_iterative(50)) # 12586269025 — instant print(fib_memo(50)) # 12586269025 — instant # fib_recursive(50) would take minutes # Python's recursion limit print(sys.getrecursionlimit()) # 1000 # sys.setrecursionlimit(10000) # raise if needed
12586269025
1000
Converting Recursive DFS to Iterative
Any recursive algorithm can be made iterative by managing your own stack — replacing the call stack with an explicit data structure.
# Recursive DFS — clean but limited by call stack depth def dfs_recursive(graph, node, visited=None): if visited is None: visited = set() visited.add(node) print(node, end=' ') for neighbour in graph.get(node, []): if neighbour not in visited: dfs_recursive(graph, neighbour, visited) # Iterative DFS — same result, no stack overflow risk def dfs_iterative(graph, start): visited = set() stack = [start] # explicit stack replaces call stack while stack: node = stack.pop() if node in visited: continue visited.add(node) print(node, end=' ') # Push neighbours in reverse to match recursive order for neighbour in reversed(graph.get(node, [])): if neighbour not in visited: stack.append(neighbour) graph = {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F'], 'D': [], 'E': ['F'], 'F': []} print('Recursive:', end=' '); dfs_recursive(graph, 'A'); print() print('Iterative:', end=' '); dfs_iterative(graph, 'A'); print()
Iterative: A B D E F C
🎯 Key Takeaways
- Recursion is natural for tree traversal and divide-and-conquer — the code mirrors the problem structure.
- Python's default recursion limit is 1000 frames — deep recursion causes RecursionError.
- Convert recursive solutions to iterative by using an explicit stack.
- Memoization (@lru_cache) fixes the exponential time of naive recursive algorithms.
- Iteration is generally faster — no function call overhead per step.
Interview Questions on This Topic
- QWhat is Python's default recursion limit and how do you change it?
- QHow do you convert a recursive DFS to an iterative one?
- QWhat is the time complexity of naive recursive Fibonacci?
Frequently Asked Questions
What is tail recursion and does Python support it?
Tail recursion is when the recursive call is the very last operation in the function — nothing happens after it returns. Some languages (Scheme, Scala) optimise tail calls to avoid stack growth. Python deliberately does not implement tail call optimisation — Guido van Rossum decided it would make stack traces harder to debug.
When is recursion the better choice?
When the problem's structure is naturally recursive: tree traversal, divide and conquer (merge sort, quicksort), backtracking, and parsing nested structures. The recursive solution often directly mirrors the problem definition, making it easier to verify correctness.
Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.