Recursion

Quiz: counts toward finishing the lesson. Check: just for practice.

Introduction

A recursive function is a function that calls itself. Each time it calls itself, a separate copy is created that has its own values for its parameters and variables. If every copy created another copy, the recursion would never end and the computer would run out of memory. So every recursive function needs at least one base case. A base case is a case where the function doesn't call itself.

Let's look at a common first example of recursion:

The if statement checks whether num is equal to zero. This is the base case. If it's true, the function does not call itself. Otherwise, it calls itself, multiplies the return value by num, and returns the result. We could also write it like this:

The else can be left out because if the condition is true, return 1 runs and the function ends before it reaches the recursive call. The other examples in this lesson use this style.

The Call Stack

When a recursive function runs, several copies of it are active at once, but only the most recent one is executing. The others are paused, waiting for a result. When a recursive call is made, the computer saves its place in the current copy so it can come back later, then starts a new copy. It saves that place on the call stack, which keeps track of all active function calls. Watch the video "Flow of execution example for recursion" to see how this works.

Check your understanding. Predict the result. Follow each call down to the base case, then work back up.

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

x = mystery(3)
y = mystery(1)

Predict what each variable holds after the program finishes. The program is not run for you. Change the values below to your predictions:

  • final_x is the value of x at the end
  • final_y is the value of y at the end
Hint 1

Each paused copy finishes its multiply and add only after the call below it returns.

More examples

Here's a recursive function that finds the greatest common divisor of two integers:

The base case is when b evenly divides a, in which case b is the greatest common divisor. Otherwise we make a recursive call, passing b for a and a % b for b. The function just returns whatever the recursive call returns, with no extra work.

Here's a recursive function that computes the hailstone sequence starting from a given number and counts how many steps it takes to reach 1:

Here the base case is when the sequence arrives at 1. There are two recursive cases: one if num is even and one if it is odd. We add 1 to the return value, since the current copy of hailstone takes one more step to reach 1 than the recursive call does. For example, if we start at 3, the sequence goes: 3, 10, 5, 16, 8, 4, 2, 1. Once we know how many steps it takes to go from 10 to 1, we add 1 more step to get the number of steps from 3 to 1.

Writing a Recursive Function

Recursion can feel like magic, because you're writing a function that calls the function you're still writing. The general strategy is to find a way to break the problem into a smaller problem of the same kind, plus a bit of work at the current level.

Quizzes

  1. Write a recursive function called countdown that takes a positive integer parameter and returns a string that counts down from that number to 1. For example, if 5 is passed to the function, it should return the string "5 4 3 2 1". You can use string concatenation in your recursive function to build up the return value.
Hint 1

The base case is when n is 1. Otherwise, put str(n) in front of the result of countdown(n - 1).

  1. Write a recursive function called countup that takes a positive integer parameter and returns a string that counts up from 1 to that number. For example, if 5 is passed to the function, it should return the string "1 2 3 4 5". You can use string concatenation in your recursive function to build up the return value.
Hint 1

This is the mirror of countdown. Put the result of countup(n - 1) in front of str(n).

  1. Write a recursive function called sum_countup that takes an integer parameter and returns the sum of all the integers from 1 to that number. For example if the function is passed the value 5, then it should return 15 because 1 + 2 + 3 + 4 + 5 = 15.
Hint 1

The base case returns 1 when n is 1. Otherwise add n to sum_countup(n - 1).

  1. Predict the result. Look at which side of the recursive call each number goes on.
def build_up(n):
    if n == 0:
        return ""
    return build_up(n - 1) + str(n)

def build_down(n):
    if n == 0:
        return ""
    return str(n) + build_down(n - 1)

x = build_up(3)
y = build_down(3)

Predict what each variable holds after the program finishes. The program is not run for you. Change the values below to your predictions, and write strings with quotes:

  • final_x is the value of x at the end
  • final_y is the value of y at the end
Hint 1

The recursive call returns a string, and the current number is joined on one side of it.

Projects

Practice what you learned in your own editor. Each project has its own page.