How to use the Python 3 reduce() function


The Python 3 reduce() function is a pre-defined function found in the functools module. It accepts a function with two arguments and applies that function cumulatively to the items of an iterable.

In today’s post, we’ll discuss what the function does in depth. We’ll also talk about the difference between the Python 2 and Python 3 reduce() function, and why this function may not be the best option to use in most cases. Last but not least, we’ll look at alternatives to the Python 3 reduce() function.

What does the reduce() function do?

As mentioned above, the Python 3 reduce() function applies a function cumulatively to the items of an iterable.

It accepts three arguments – a function with two arguments, an iterable and an optional initializer.

Suppose we pass a function called myFunc() (with two arguments) and a list called myList to the reduce() function, this is what the function does:

  1. First, it passes the first two elements in myList to myFunc() to generate a tentative result.
  2. Next, it passes the tentative result and the third element in myList to myFunc() to update the tentative result.
  3. It keeps repeating step 2 with the remaining items in myList until it reaches the end of myList.
  4. When that happens, it returns a single value as the final result.

Let’s look at some actual examples of how the Python 3 reduce() function works.

Example 1: Finding the sum of numbers in a list

Example 1.1 Using named function

We can use the reduce() function to find the sum of all numbers in a list.

from functools import reduce

myList = [10, 12, 17, 42]

def add2Numbers(a, b):
    return a+b

total = reduce(add2Numbers, myList)
print(total)

Here, we first import the reduce() function using the import statement on line 1.

Next, we declare and initialize a list called myList.

On lines 5 and 6, we define a function called add2Numbers() that accepts two arguments – a and b. This function returns the sum of a and b.

On line 8, we call the reduce() function, passing the add2Numbers() function and the myList list to the function.

The reduce() function does the following:

  1. It first passes the first two elements in myList to the add2Numbers() function. In other words, it passes the numbers 10 and 12 to the add2Numbers() function to get 22 as the tentative result.
  2. Next, it passes the tentative result (22) and the third element in myList (17) to the add2Numbers() function again. This updates the tentative result to 39.
  3. Finally, it passes 39 and the last element in myList (i.e. the number 42) to the add2Numbers() function to get 81 as the final result.

Once it reaches the last element in myList, it returns the final result.

If you run the code above, you’ll get the following output:

81

Example 1.2 Using operator.add()

The example above shows how we can use the reduce() function to cumulatively apply a user-defined function (add2Numbers) to a list (myList).

In addition to using the reduce() function to apply a user-defined function, we can use it to apply a pre-defined function in Python.

An example is shown below:

from functools import reduce
from operator import add

myList = [10, 12, 17, 42]

total = reduce(add, myList)
print(total)

This example very similar to the previous example. The main difference is instead of passing the user-defined add2Numbers() function to reduce(), we pass the add() function.

The add() function is a pre-defined function available in the Python operator module. It does the same thing as the add2Numbers() function. In other words, it accepts two arguments and returns their sum.

Therefore, if you run the code above, you’ll get 81 as the output as well.

Example 1.3 Using lambda function

Besides passing user-defined or pre-defined functions, we can pass a lambda function to the reduce() function.

The code below achieves the same result as the previous two examples:

from functools import reduce

myList = [10, 12, 17, 42]

total = reduce(lambda a, b: a+b, myList)
print(total)

Here, we pass the following lambda function to the reduce() function.

lambda a, b: a+b

If you are not familiar with lambda functions, you can check out the post here.

If you run the example above, you’ll get 81 as the output, similar to the previous two examples.

Example 2: Finding the smallest number in a list

Now that we’ve seen three variations of how we can use the reduce() function to find the sum of numbers in a list, let’s look at another application of the reduce() function.

In this example, we’ll use the reduce() function to find the smallest number in a list.

This can be achieved with the code below:

from functools import reduce

myList = [45, 2, 12, -3, 56]

def getSmaller(a, b):
    if a < b:
        return a
    else:
        return b

smallest = reduce(getSmaller, myList)
print(smallest)

Here, the reduce() function first passes 45 and 2 to the getSmaller() function to compare the first two elements in myList. This gives us 2 as the tentative result.

Next, the reduce() function passes this tentative result (2) and the third element in myList (12) to getSmaller() to get the smaller number among the two. This gives us 2 as the result as well.

The function keeps comparing each tentative result with the next element in myList until it reaches the end of the list.

If you run the code above, you’ll get the following output:

-3

Example 3: Using the reduce() function with an initializer

Besides passing a function and an iterable, we can pass a third optional argument to the reduce() function. This argument is known as an initializer.

When the initializer is provided, the reduce() function starts by passing the initializer and the first element in the iterable to the function.

Let’s look at an example:

from functools import reduce

myList = [10, 12, 17, 42]

def add2Numbers(a, b):
    return a + b

total = reduce(add2Numbers, myList, 500)
print(total)

Here, we pass 500 as the initializer to the reduce() function.

The reduce() function first passes 500 and 10 (the first element in myList) to the add2Numbers() function. This gives us 510 as the tentative result.

Next, the reduce() function passes this tentative result (510) and the second element in myList (12) to add2Numbers() again to get 522 as the new tentative result.

It keeps doing that until it reaches the end of myList.

If you run the code above, you’ll get

581

as the output.

Error Thrown by the reduce() function

The reduce() function throws a TypeError if you pass an empty iterable to it AND do not pass an initializer. For instance, if you run the code below,

from functools import reduce
from operator import add

# Empty list
myList = []

# With initializer
total = reduce(add, myList, 0)
print(total)

# Without initializer
total = reduce(add, myList)
print(total)

you’ll get the following output:

0
Traceback (most recent call last):
  File "...", line 12, in <module>
    total = reduce(add, myList)
TypeError: reduce() of empty sequence with no initial value

When we call the reduce() function with an empty list and an initializer (on line 8), it returns the initializer as the output (first line in the output above).

However, if you pass an empty list and do not provide the initializer, you get an error.

Difference between the Python 2 and Python 3 reduce() function

Now that we are familiar with how the reduce() function works, let’s discuss the difference between the Python 2 and Python 3 reduce() function.

The Python 2 reduce() function is always available. In other words, to use the function, you do not need to import any module.

In contrast, in Python 3, the reduce() function was moved to the functools module. To use this function, you need to import the functools module.

Criticism of the reduce() function

The reduce() function has always been a controversial function.

The creator of Python Guido van Rossum personally stated that this is the function he hated the most. The main reason is the function makes our code less readable. It tends to complicate things unnecessarily as “99 percent of the time an explicit for loop is more readable.”.

For instance, in our Example 1 above, if we want to find the sum of numbers in a list, we can easily do it using a for loop, as shown in the code below:

total = 0
myList = [10, 12, 17, 42]

for i in myList:
    total += i

print(total)

Or better still, we can use the built-in sum() function in Python, as shown in the code below:

myList = [10, 12, 17, 42]

total = sum(myList)
print(total)

Both methods are easier to understand than the reduce() function.

Therefore, unless there is a compelling reason to use the reduce() function, you may want to use a loop instead.

Practice Question

Now that we’ve completed our discussion of the Python 3 reduce() function, let’s move on to our practice question.

Today’s practice question is a bit different. You’ll be given a piece of code that uses the reduce() function and your task is to rewrite the code using a loop.

Ready? Here goes.

Rewrite the following code using a loop:

from functools import reduce

items = [112, 5122, 43, 644, 215, 9876]

def myFunc(x, y):
    if x > y:
        return x - y
    else:
        return y - x

result = reduce(myFunc, items)

print(result)

The code above gives us 5768 as the output.

Suggested Solution

items = [112, 5122, 43, 644, 215, 9876]
result = items[0]

for i in items[1:]:
    if i > result:
        result = i - result
    else:
        result = result - i

print(result)

Here, we first declare a variable called result and initialize it to the first element in items (line 2).

Next, we use a for loop (lines 4 to 8) to iterate through the remaining elements in items (i.e. items[1:]).

Inside the for loop, we compare each element with the tentative result (result) and update result accordingly based on whether the element is greater than result. This is similar to what the myFunc() function does in our practice question above.

Finally, we print the value of result on line 10.

If you run the code above, you’ll get 5768 as the output.

Written by Jamie | Last Updated November 15, 2020

Recent Posts