Python Recursion, Explained Like Russian Nesting Dolls
Open a matryoshka doll and you find a smaller doll inside. Open that one, and there's an even smaller doll. You keep going until you reach the tiniest doll that doesn't open at all, that's where the process stops. Recursion in Python works exactly like this: a function that calls a smaller version of itself, until it hits a point where it stops calling and just answers directly.
What Recursion Actually Is
A recursive function is a function that calls itself, working on a smaller piece of the problem each time.
def open_doll(size): if size == 0: print("Smallest doll, no more inside") return print(f"Opening doll of size {size}"Output:
The Two Parts Every Recursive Function Needs
Every matryoshka set eventually has a doll that doesn't open. Every recursive function needs the same thing:
- Base case: the condition where the function stops calling itself. Without this, you'd be opening dolls forever, an infinite loop that crashes your program.
- Recursive case: the part where the function calls itself with a smaller version of the problem.
In the example above,
if size == 0is the base caseopen_doll(size - 1)is the recursive case.
A Practical Example: Factorial
The classic textbook example is calculating a factorial (5! = 5 × 4 × 3 × 2 × 1).
def factorial(n): if n == 0: # base case return 1 return n * factorial(n - 1) # recursive case print(factorial(5)) # 120Here,
- We have
n * factorial(n - 1)(recursive call) - When we call
factorial(5), Python does not immediately calculate the answer. It keeps calling the function with a smaller number:5 * factorial(5-1)i.e. 5 × factorial(4)
- When
nbecomes1, the base case runs and returned1
A Real-Life Use Case: Searching Nested Folders
Recursion isn't just a classroom exercise. File systems are naturally nested, folders inside folders, exactly like the dolls.
Every subfolder is just a smaller version of the same problem: "count the files in this folder." That's exactly why recursion fits it so naturally, some problems are inherently nested, and forcing a non-recursive solution would be more complicated than the recursive one.
The Danger: Forgetting the Base Case
If you forget the base case, or if it's never actually reached, the dolls never stop opening.
Python has a default recursion limit (usually 1000) specifically to catch this kind of mistake before it crashes your computer.
Recursion vs. Loops
Anything recursion can do, a loop can technically also do. Recursion tends to read more naturally for problems that are already nested or tree-shaped, like folder structures or family trees. For simple repetition, like printing numbers 1 to 10, a plain loop is usually clearer and uses less memory, since every recursive call adds a new layer to Python's call stack.
What's Next
You now understand functions that call themselves. The final tutorial in this series covers closures and decorators, functions that wrap other functions, the same trick behind popular tools like Flask's @app.route.
Python Functions 7-Part Masterclass:
- Part 1: Python Functions Explained Like a Recipe (Beginner's Guide)
- Part 2: Python Function Parameters and Arguments (Explained Like Ordering Food)
- Part 3: *args and **kwargs in Python Explained Like a Potluck Party
- Part 4: Python Lambda Functions Explained Like a Sticky Note
- Part 5: Python Variable Scope Explained Like an Office Building
- Part 6: Python Recursion Explained Like Russian Nesting Dolls (Current)
- Part 7: Python Closures and Decorators Explained Like Gift Wrapping