1def fact(n):2 if n <= 1:3 return 14 return n * fact(n - 1)56print(fact(4))depth 0fact(4)n=4fact(3)n=3fact(2)n=2fact(1)n=1
Code card: fact(n); highlighted lines are the ones the step is aboutCall stack: one block per running call of fact, newest on topScreen: where print shows its outputFront row: how many times naive fib(5) calls fib(n)Each call of fact gets its own block on the call stack, holding its own n. Calls carry a smaller n up to a new block on top; the base case answers without calling; then the blocks come off the top one by one, each handing its value to the block below, which multiplies it by its own n. fact(4) = 4 * 3 * 2 * 1 = 24. Python stops a chain of calls deeper than sys.getrecursionlimit() (1000 by default) with a RecursionError. The front row counts the 15 calls naive fib(5) makes. The drawing shows one block for each call of fact that is still running, stacked in the order the calls started. In CPython every call gets its own frame object; when the call returns, the frame is released.

Calls stack up

  1. Line 6 calls fact(4). Python makes a call frame for it: scratch space that holds this call’s own n, here 4. fact is recursive: to find its answer, it calls itself on a smaller problem.

Base case

Unwinding

Limits and loops

Repeated work

Try it in the Python prompt

;; step 1/12 · line 6: print(fact(4))
>>> def fact(n):
...     if n <= 1:
...         return 1
...     return n * fact(n - 1)
...
>>> fact(4)
24

The drawing shows one block for each call of fact that is still running, stacked in the order the calls started. In CPython every call gets its own frame object; when the call returns, the frame is released. The depth shown counts only fact’s frames. The code that called fact(4) runs in a frame too, so Python’s own count is a little higher, which is why fact(999) still works in a fresh python3 -c run and fact(1000) does not.