Saturday, November 14, 2026 New tutorials published every day
Home
Tutorials
Core PHP PHP Course JavaScript React & Next.js Python WordPress Artificial Intelligence
Free Tools
JSON Formatter Base64 Encoder / Decoder Password Generator Text to QR Code Generator Word Counter Case Converter Age Calculator Color Converter Number to Words All Free Tools
Projects
PHP Projects — all projects
Students
Webflow Course Course Registration Download Syllabus Verify Certificate Student Leaderboard
Resources
WordPress Plugins Search tutorials About CodingCush Contact
More
Login
Data Structures

Recursion Explained with Simple Python Examples

Recursion explained for beginners with simple Python examples: countdown, factorial and Fibonacci, plus base cases, the call stack and common mistakes.

Recursion is when a function calls itself to solve a smaller version of the same problem, again and again, until it reaches a simple case it can answer directly. That simple case is the base case, and it stops the function from calling itself forever. In this article you will run four complete Python examples: a countdown, a factorial, the Fibonacci sequence, and the sum of a list. You will also learn how the call stack works, what the Python recursion limit is, and which beginner mistakes to avoid.

What Is Recursion, in Plain Words?

Imagine you are in a long queue and want to know your position. You ask the person in front, who asks the person in front of them, until the question reaches the first person, who can answer at once: "I am number one." The answer then travels back, each person adding one, until you know your position.

That is recursion. A big problem is passed on as a smaller problem until the answer is obvious, and the small answers are combined on the way back. To revise functions first, see the official tutorial section on defining functions and control flow in Python.

The Two Parts Every Recursive Function Needs

The base case is the smallest version of the problem, the one the function can answer directly without calling itself. In the queue story, it is the first person.

The recursive case is everything else. The function does a small piece of work, then calls itself with an input one step closer to the base case. Every call must move closer, or the function will never stop.

Example 1: A Simple Countdown

The countdown is the friendliest first example, because you can watch the calls in the output. The function prints a number, then calls itself with a number one smaller.

def countdown(n):
    if n <= 0:
        print("Blast off!")
    else:
        print(n)
        countdown(n - 1)

countdown(5)

The line if n <= 0 is the base case. The else block is the recursive case: it prints the number and calls countdown(n - 1), one step closer to zero. The output is:

5
4
3
2
1
Blast off!

Example 2: Factorial of a Number

The factorial of a number is that number multiplied by every whole number below it down to one, so 5! is 5 x 4 x 3 x 2 x 1, which equals 120. It also has a neat recursive definition: n! equals n multiplied by (n - 1)!.

def factorial(n):
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))
print(factorial(0))

The base case says the factorial of 0 and of 1 are both 1. The recursive case returns n * factorial(n - 1), so factorial(5) becomes 5 x factorial(4), then 4 x factorial(3), until factorial(1) returns 1 and the multiplications happen on the way back. The output is:

120
1

Example 3: Fibonacci Numbers

In the Fibonacci sequence, each number is the sum of the two before it: 0, 1, 1, 2, 3, 5, 8, 13, and so on. This one needs two base cases.

def fibonacci(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(6))
print([fibonacci(i) for i in range(8)])

The recursive case adds two smaller calls. The output is:

8
[0, 1, 1, 2, 3, 5, 8, 13]
Terminal window showing the real Python output of the recursion examples in this article, including the countdown, factorial and Fibonacci results
A terminal window showing the real output of this article's Python recursion examples, including the countdown, the factorial results and the Fibonacci sequence.

A friendly warning: this neat version is slow for larger numbers, because it repeats work. Finding fibonacci(6) calls fibonacci(5) and fibonacci(4), and fibonacci(5) calls fibonacci(4) again, so the same problems get solved many times and the calls grow very fast. Storing results in a dictionary, called memoisation, can fix this. Growth like this is easier to judge with our guide to Big O notation and how algorithm growth is measured and our walkthrough of time complexity in Python with everyday examples.

Example 4: Sum of a List

The sum of a list is the first item plus the sum of the rest, and the sum of an empty list is zero, which is the base case.

def sum_list(numbers):
    if not numbers:
        return 0
    return numbers[0] + sum_list(numbers[1:])

print(sum_list([1, 2, 3, 4, 5]))

Each call takes the first number out and asks a smaller call to handle the rest. The output is:

15

In real projects you would use the built in sum() function, which is shorter and faster. The recursive version is still worth learning, because the same pattern appears in trees, nested folders, and interview questions.

What Is the Call Stack?

When a function calls itself, Python must remember where each unfinished call stopped and where to return its result. It stores this on the call stack, which you can picture as a pile of plates: each new call adds a plate, and a call can only finish when the calls above it have finished.

Take factorial(3). It waits for factorial(2), which waits for factorial(1), the base case, which returns 1. Then the stack unwinds: factorial(2) returns 2, and factorial(3) returns 6. This last in, first out behaviour is why the stack matters, and our comparison of the stack and queue data structures and their key differences explains it with more examples.

The Python Recursion Limit and RecursionError

Every unfinished call uses memory, so Python protects your program with a recursion limit. Call too deeply and Python raises a RecursionError instead of crashing. Check your limit like this:

import sys

print(sys.getrecursionlimit())

On the machine used to test this article, the output was:

1000

Your number will most likely also be 1000, the usual default. The official documentation for the sys module in Python describes this limit in detail. You can raise it with sys.setrecursionlimit(), but treat that as an expert tool, not a fix: hitting the limit usually means a missing base case, so fix the logic first.

Recursion or a Loop: Which Should You Use?

Anything written with recursion can also be written with a loop. Use the version that is clearer and safer for your data size.

Point to compare Recursion Loop
How it repeats A function calls itself with a smaller input A for or while block repeats steps
How it stops When the base case is reached When the loop condition becomes false
Memory use Uses the call stack, so deep calls cost memory Usually uses very little extra memory
Best for Trees, nested data, divide and conquer problems Simple counting, lists, long repetition
Main risk RecursionError if the calls go too deep An infinite loop if the condition never changes

A simple rule: if the problem is nested or branching, try recursion. If it is a long, straight line of steps, use a loop.

Common Mistakes and Troubleshooting

Forgetting the base case. The function calls itself until Python raises a RecursionError. Fix: write the base case first, every time.

The input never gets smaller. Calling countdown(n) instead of countdown(n - 1) means the base case is never reached. Fix: check every call moves closer to it.

Forgetting to return the recursive call. Writing factorial(n - 1) on its own throws the answer away, and the function returns None. Fix: the recursive call is usually part of a return statement.

Expecting the naive Fibonacci code to be fast. It repeats work, so large inputs crawl. Fix: use a loop, or store results already worked out.

Raising the limit to hide a bug. A higher limit only delays the crash. Fix: print the argument for a small input and check the values move towards the base case.

Frequently Asked Questions

Is recursion hard to learn?

No, it only feels strange at first. Trace one small example on paper and the idea usually clicks within an hour.

What happens if a recursive function has no base case?

It keeps calling itself until Python raises a RecursionError, so always write the base case first.

Is recursion faster than a loop in Python?

Usually no. Loops are normally faster and use less memory. Recursion wins on clarity for nested problems, not speed.

When should I use recursion in real projects?

Use it when the data is nested, such as folders inside folders, comments with replies, or splitting a problem into halves.

Conclusion

Recursion is simply a function that calls itself on a smaller problem until it reaches a base case it can answer directly. You have seen it count down, build a factorial, grow the Fibonacci sequence, and add up a list. Pick one example, type it yourself, break it by removing the base case, then fix it. That small experiment teaches more than ten definitions. Happy coding, and yes, this conclusion was written by a human, not by a function calling itself.

Lavkush
Written by

Lavkush Super Admin

Lavkush Kumar is a software developer with over 6 years of experience turning ideas into websites and web applications. He holds a Master of Computer Applications (MCA) degree and enjoys building for the web, exploring new tools, and sharing what he learns along the way.

Through CodingCush, Lavkush creates easy-to-follow tutorials and practical guides to help students and beginners learn software development without feeling overwhelmed. His approach is simple: learn by doing, build real projects, and keep improving one step at a time.

Whether you’re just starting out or looking to sharpen your skills, CodingCush is all about making learning practical, beginner-friendly, and fun.

0 Comments

Leave a Comment