Recursion
Be able to write recursive functions and understand base cases and the call stack.
Prerequisites
Intuition
A recursive function calls itself on a smaller problem, until the problem is so small that the answer is obvious.
Two parts are required, always:
- A base case — when should it stop? Without one: infinite recursion and a
RecursionError. - A recursive step — the problem has to get smaller every time.
def factorial(n):
if n <= 1: # the base case
return 1
return n * factorial(n - 1) # a smaller problem
factorial(4) → 4 · factorial(3) → 4 · 3 · factorial(2) → 4 · 3 · 2 · factorial(1) → 4 · 3 · 2 · 1 = 24.
Code
# Recursion shines when the data itself is nested — trees, directories, JSON, graphs
def depth(obj):
"""How many levels of nested lists?"""
if not isinstance(obj, list):
return 0
return 1 + max((depth(x) for x in obj), default=0)
print(depth([1, [2, [3, [4]]]])) # 3
# A prerequisite tree — the same pattern as the platform's learning paths
def all_prerequisites(slug, graph, seen=None):
seen = seen if seen is not None else set()
for f in graph.get(slug, []):
if f not in seen:
seen.add(f)
all_prerequisites(f, graph, seen)
return seen
g = {"backprop": ["neuralnet"], "neuralnet": ["matrices", "derivative"], "matrices": ["vectors"]}
print(sorted(all_prerequisites("backprop", g)))
# ['derivative', 'matrices', 'neuralnet', 'vectors']
A warning: Python handles about 1 000 levels of recursion depth. For deep structures or simple loops, iteration is better. Fibonacci recursively without memoisation is moreover exponentially slow — functools.cache solves that.
Mastery means
- Writes a recursive function with a base case
- Follows the call stack
- Recognises when recursion is natural
Sign in to do the exercises and build your mastery up.