Thuta Learning
BasicProgrammingintermediate

Recursion Basics

What you'll walk away with

  • Explain the core ideas behind Recursion Basics
  • Run the sample Python code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

Recursion solves a problem by breaking it into a smaller version of the exact same problem, and calling the function itself to solve that smaller piece. Every correct recursive function needs two parts: a base case, the smallest input the function can answer directly without recursing further, and a recursive case, where it calls itself on a smaller input and combines that result with the current step's work. Consider factorial(n): the base case is factorial(0) = 1, answered immediately with no further call; the recursive case is factorial(n) = n * factorial(n - 1) for n > 0. Calling factorial(3) doesn't compute an answer right away — it calls factorial(2), which calls factorial(1), which calls factorial(0), each new call pausing its caller and pushing a fresh frame onto the call stack. Once factorial(0) returns 1, that answer flows back up: factorial(1) returns 1*1=1, factorial(2) returns 2*1=2, factorial(3) returns 3*2=6 — the stack unwinding in the exact reverse order it built up. If the base case is missing, wrong, or never reached (e.g. counting the wrong direction), calls keep pushing new frames forever, exhausting the call stack and crashing with a stack overflow.

Connect it to a real scenario

The Tutorial Platform's course content is naturally nested — a course contains chapters, each chapter contains lessons — which is exactly the shape recursion is built for. A function that renders a table of contents, or one that walks a lesson's prerequisite chain to check 'has the learner completed everything required before this lesson', can process a chapter or a prerequisite the same way it processes the whole course: solve the smallest case (a single lesson with no prerequisites) directly, and delegate everything larger to a recursive call on its sub-parts. Getting the base case right here is what stops that prerequisite check from looping forever if two lessons ever end up referencing each other.

Try the working example

python
def factorial(n):
    # Base case: smallest input, answered directly, no further recursion
    if n == 0:
        return 1
    # Recursive case: solve a smaller subproblem, then combine with current step
    return n * factorial(n - 1)

# Trace for factorial(3):
#   factorial(3) -> 3 * factorial(2)
#     factorial(2) -> 2 * factorial(1)
#       factorial(1) -> 1 * factorial(0)
#         factorial(0) -> 1                (base case reached, stack starts unwinding)
#       factorial(1) returns 1 * 1 = 1
#     factorial(2) returns 2 * 1 = 2
#   factorial(3) returns 3 * 2 = 6
print('factorial(3) =', factorial(3))
You should see
Prints 'factorial(3) = 6', matching the traced call stack in the comments: four nested calls build up to factorial(0), then results unwind back up (1, 1, 2, 6).

5-minute try-it

Write a recursive function sum_list(items) that returns the sum of a list of numbers, with an empty list as the base case. Then deliberately remove the base case and run it to observe the RecursionError / stack overflow, and explain in a comment why it happens.

One important caution

Writing the recursive case so the input never actually shrinks toward the base case (e.g. calling factorial(n) instead of factorial(n - 1) by mistake), which causes infinite recursion even though a base case exists on paper.

Assuming recursion is always the right or most efficient choice — a deeply recursive call on large input (e.g. summing a list of a million numbers) can hit Python's recursion limit and crash, where an iterative loop would run fine with no stack growth.

Wikipedia — Recursion (computer science)Data Structures & Algorithms

Easy traps

  • Writing the recursive case so the input never actually shrinks toward the base case (e.g. calling factorial(n) instead of factorial(n - 1) by mistake), which causes infinite recursion even though a base case exists on paper.
  • Assuming recursion is always the right or most efficient choice — a deeply recursive call on large input (e.g. summing a list of a million numbers) can hit Python's recursion limit and crash, where an iterative loop would run fine with no stack growth.
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Write a recursive function sum_list(items) that returns the sum of a list of numbers, with an empty list as the base case. Then deliberately remove the base case and run it to observe the RecursionError / stack overflow, and explain in a comment why it happens.

You'll know it worked when: Prints 'factorial(3) = 6', matching the traced call stack in the comments: four nested calls build up to factorial(0), then results unwind back up (1, 1, 2, 6).