Recursion Explained With Simple Examples

Abstract generated cover for Recursion Explained With Simple Examples.

Recursion is when a function calls itself. That definition is short, but it can feel strange the first time you see it. Why would a function call itself? Wouldn't it run forever? It can run forever if you write it incorrectly. But when recursion is written carefully, it is a clean way to solve problems that can be broken into smaller versions of the same problem. The key is understanding two parts:

  • the base case
  • the recursive case Once those two ideas click, recursion becomes much less mysterious.

The Mental Model

A recursive function solves a problem by saying:

  1. If the problem is simple enough, return the answer.
  2. Otherwise, solve a smaller version of the same problem. The simple-enough case is called the **base case**. The smaller-version step is called the **recursive case**. Without a base case, recursion does not know when to stop.

A Countdown Example

Here is a simple recursive countdown:

def countdown(number):
    if number == 0:
        print("done")
        return

    print(number)
    countdown(number - 1)

Usage:

countdown(3)

Output: ```plain text 3 2 1 done

The base case is:
```python
if number == 0:

The recursive case is:

countdown(number - 1)

Each call gets closer to the base case. That is the most important rule in recursion.

Factorial Example

Factorial is a classic recursion example. `5!` means: ```plain text 5 * 4 * 3 * 2 * 1

We can define it recursively:
```plain text
factorial(5) = 5 * factorial(4)
factorial(4) = 4 * factorial(3)
factorial(3) = 3 * factorial(2)
factorial(2) = 2 * factorial(1)
factorial(1) = 1

In Python:

def factorial(number):
    if number == 1:
        return 1

    return number * factorial(number - 1)

Usage:

print(factorial(5))  # 120

Again, there is a base case and a recursive case.

The Call Stack

Recursion works because function calls are stored on the call stack. When `factorial(5)` calls `factorial(4)`, Python needs to remember that `factorial(5)` is waiting for a result. The stack builds up: ```plain text factorial(1) factorial(2) factorial(3) factorial(4) factorial(5)

When the base case returns, the calls unwind:
```plain text
factorial(1) returns 1
factorial(2) returns 2 * 1
factorial(3) returns 3 * 2
factorial(4) returns 4 * 6
factorial(5) returns 5 * 24

That final result is `120`. This is why understanding stacks helps with recursion.

Recursion With Lists

Here is a recursive function to sum a list:

def recursive_sum(numbers):
    if not numbers:
        return 0

    return numbers[0] + recursive_sum(numbers[1:])

Usage:

print(recursive_sum([1, 2, 3, 4]))  # 10

The base case is an empty list. The recursive case adds the first number to the sum of the rest. This is a nice mental model, but in real Python, slicing creates new lists, so an iterative version may be more efficient.

def iterative_sum(numbers):
    total = 0

    for number in numbers:
        total += number

    return total

Recursion is not always the best implementation. It is a way to think about certain problems.

Common Mistakes

Mistake 1: Forgetting the base case

Without a base case, recursion keeps going until the program crashes.

def broken():
    broken()

Python will eventually raise a recursion error.

Mistake 2: Not moving toward the base case

This has a base case, but still fails:

def countdown(number):
    if number == 0:
        return
    countdown(number)

The value never changes, so the function never gets closer to stopping.

Mistake 3: Using recursion when a loop is clearer

Some problems are naturally recursive. Others are simpler with a loop. If a loop is easier to read and performs well, use the loop. Recursion is a tool, not a requirement.

Where This Shows Up in Real Projects

Recursion appears naturally in problems with nested structures:

  • file trees
  • menu trees
  • comments and replies
  • organization charts
  • nested JSON
  • tree traversal
  • backtracking problems For example, if you need to render nested categories, recursion can be a clean fit because each category may contain smaller categories.

Key Takeaways

  • Recursion is when a function calls itself.
  • Every recursive function needs a base case.
  • The recursive case should move toward the base case.
  • The call stack tracks unfinished function calls.
  • Recursion is useful for nested or self-similar problems.
  • Loops are sometimes simpler and more efficient.

    Related Articles

  • Stacks Explained With Real Examples

  • Big O Notation Explained With Python Examples
  • Linked Lists Explained From Scratch

← Back to Blog Index