October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

Python Recursion: Write Functions That Reach a Base Case

Python recursion uses a base case to stop and a recursive step to simplify a problem. See a factorial example, caching trade-offs, and when to use a loop.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In Python, recursion means a function calls itself to solve a smaller or simpler version of a problem. A sound recursive function has a base case that stops the calls and a recursive step that moves each call toward that case. Those two parts make recursion useful—and help prevent a runaway chain of calls.

What recursion means in Python

When a function calls itself, Python starts another function call with its own local symbol table. That call has its own local variables and runs independently while the earlier call waits for a result. Once the new call returns, execution resumes in the waiting call.

As an Amazon Associate I earn from qualifying purchases.

This creates a chain of active calls. Recursion fits problems that can be expressed as smaller instances of the same problem, such as traversing nested structures or calculating a value from a smaller input. The Python tutorial explains both function-call behavior and recursive functions in its control-flow tutorial.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to write a recursive function

Build every recursive function around two parts:

  • Base case: the condition under which the function returns without calling itself again.
  • Recursive step: the part that calls the function with an input closer to the base case.

If the recursive step does not make progress toward the stopping condition, calls can continue until Python raises RecursionError.

Example: factorial with a base case

For a nonnegative integer n, factorial is the product of the integers from 1 through n; by convention, 0! is 1. This implementation expects a nonnegative integer:

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

Identify the two parts

  • Base case: when n == 0, return 1 without another call.
  • Recursive step: otherwise, multiply n by the factorial of n - 1. Subtracting 1 moves the input toward zero.

Trace factorial(4)

The calls proceed as 4 * factorial(3), 3 * factorial(2), 2 * factorial(1), and 1 * factorial(0). The base case returns 1; as each call finishes, its waiting multiplication resolves. The final result is 24.

Recursion, repeated work, and memoization

Recursion describes how a solution is structured; it does not automatically make the computation efficient. A naïve recursive Fibonacci function, for example, recalculates the same subproblems many times. When calls repeat with the same arguments, caching can avoid some of that repeated work.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Python’s functools.cache, available from Python 3.9, stores results for arguments that can be used as dictionary keys. Here is the factorial example with caching:

from functools import cache

@cache
def factorial(n):
    return n * factorial(n - 1) if n else 1

The functools documentation describes cache as an unbounded cache equivalent to lru_cache(maxsize=None). Its example reports that the first call to factorial(10) makes 11 calls, while later calls using cached arguments can return without new calls. This is the documentation’s example, not a performance guarantee for other workloads.

Caching helps when subproblems repeat, but it does not shorten a single chain of nested calls. An unbounded cache also retains entries, so a workload with many distinct arguments can use more memory. Consider both call depth and retained results when choosing an approach.

Recursion or a loop?

Neither approach is always better. Choose based on the structure of the problem and the behavior of the implementation:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Consideration Recursion Iteration
Call depth Each nested call adds to the active call chain; a long chain can reach Python’s recursion limit. A loop can handle a long linear sequence without adding one function call per item.
Repeated subproblems Repeated calls can redo work; memoization may help when arguments repeat and are cacheable. A loop can carry forward results directly when the calculation has a simple sequential structure.
Memory Active calls use call frames; caching retains results as well. A loop often avoids a deep call chain, though its own data structures still use memory.
Clarity Can mirror nested data or a problem naturally defined in terms of smaller instances. Can be easier to trace for a long, straightforward sequence.

Python’s tutorial demonstrates Fibonacci generation with a while loop. For a deep linear process, an iterative design is often preferable; for nested or divide-and-conquer structure, recursion may express the logic more directly. These are design considerations, not a promise that one version will run faster in every case.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Why Python raises RecursionError

RecursionError is a subclass of RuntimeError. Python raises it when the interpreter detects that the maximum recursion depth has been exceeded, as documented under built-in exceptions. Common causes include a missing base case, a recursive step that fails to approach it, or a valid but unusually deep chain of calls.

Check the function’s stopping condition and trace whether each recursive argument moves toward it. If the function is correct but the required chain is very deep, consider whether a loop or a redesigned algorithm can avoid that depth.

Checking and changing the recursion limit

sys.getrecursionlimit() returns the interpreter’s current recursion limit. Python uses a limit to help prevent infinite recursion from overflowing the C stack. The sys documentation also describes sys.setrecursionlimit(), but warns that the highest safe value depends on the platform and that setting the limit too high can crash Python.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import sys

print(sys.getrecursionlimit())

Changing the limit should not be the routine response to RecursionError. First verify that the recursive function has a reachable base case and makes progress. For work that requires a very deep linear chain, prefer an iterative solution or another redesign; raise the limit only when you understand the platform and stack-safety implications.

Further reading

For a book focused specifically on recursive programming, Al Sweigart’s The Recursive Book of Recursion uses Python and JavaScript examples. Publisher information is available from No Starch Press and Penguin Random House.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.