## Introduction

The **Python reduce() function** aggregates all items in an iterable. It works iteratively by

**combining**each item in succession with the previously calculated aggregate value. You can think of

`reduce()`

as a function that *reduces*a collection of values into a single value, and that’s where it gets its name. For example, a list of numbers can be reduced to a single multiplicative product by successively multiplying each item in the list with the previously calculated product.

The `reduce()`

function is part of the `functools`

module, and must be imported from there using a from-import statement. Its utility lies in simplifying code that involves iterative aggregation, offering a concise alternative to traditional loops.

## Basic Python *reduce()* Function Syntax

The basic syntax of the `reduce()`

function involves passing a function (which can also be a lambda expression) and an iterable as arguments. The function should take two arguments, perform the desired operation on those and return its result. The `reduce()`

function successively applies this function to the elements of the iterable, accumulating a single result.

The following is the `reduce()`

syntax:

from functools import reduce reduce(function, iterable[, initializer])

`function`

: The function to apply cumulatively to the items of the iterable.`iterable`

: The iterable whose elements will be aggregated.`initializer`

: An optional argument providing the initial value for the aggregation. If not provided, the first element of the iterable is used. (The square brackets are not part of the syntax, and they are only there to indicate the optional nature of the argument.)

The following example shows how to use `reduce()`

to find the multiplicative product of all numbers in a list.

**Example:**

from functools import reduce numbers = [2, 3, 4, 5] product = reduce(lambda x, y: x * y, numbers) print(product)

**Output:**

120

In this example:

`lambda x, y: x * y`

: The lambda function that defines the multiplication operation between two elements. The`x`

argument receives the accumulated value and`y`

the next item from the iterator.`numbers`

: The original list of numbers.`reduce(lambda x, y: x * y, numbers)`

: Applies the multiplication function cumulatively to all elements in the list.

Unlike `map()`

, the result of `reduce()`

is not an iterable but a single value that is the cumulative operation on all elements. This is why there is no need to convert the result to a list or other object before printing.

## The Accumulation Process

Let’s take a closer look at how the accumulation process of the `reduce()`

function works by replacing the lambda expression in the last example with an equivalent function that also prints out its arguments

**Example:**

from functools import reduce def mult(x, y): print(f"Accumulated value: {x} Next value: {y}") return x * y numbers = [2, 3, 4, 5] product = reduce(mult, numbers) print(f"Final product: {product}")

**Output:**

Accumulated value: 2 Next value: 3 Accumulated value: 6 Next value: 4 Accumulated value: 24 Next value: 5 Final product: 120

As you can see in line 1 of the output, the initial accumulated value is `2`

. Since `map()`

was not called with an `initializer`

argument, it defaults to the first item in the `numbers`

list, `2`

. Consequently, in the absence of an initializer, the first call to the function is made with the first two items of the iterator as arguments.

After the first call, the accumulated value is the returned result of the previous function call. For example, the accumulated value of the second call (line 2) is 6. It is the product of 2 and 3, which are the function arguments in the first call (line 1). And the accumulated value of the third call (line 3) is 24. It is the product of 6 and 4, which are the function arguments in the second call (line 2).

## Using *reduce()* with an Initializer

The `initializer`

argument is optional, but it can be useful in certain scenarios. If provided, it becomes the initial value for the cumulative operation. This can be particularly handy when working with an iterable that might be empty.

**Example:**

from functools import reduce numbers = [] result = reduce(lambda x, y: x + y, numbers, 0) print(result)

**Output:**

0

In the example above, the `reduce()`

function is used to sum numbers in a list. It starts with an initial value of 0, which is given as the third argument. In case the `numbers`

list is empty, the result would be 0, which makes sense for a sum.

Python will generate a `TypeError`

if `reduce()`

is given an empty iterable with no initial value:

**Example:**

from functools import reduce numbers = [] result = reduce(lambda x, y: x + y, numbers) print(result)

**Output:**

... TypeError: reduce() of empty sequence with no initial value

## Non-Commutative Operations

In a commutative operation, the order of the items operated on does not matter. Both addition and multiplication are examples of commutative operations. Therefore, in the previous examples, it wouldn’t make a difference if we flip the accumulated and next value arguments in the function. For instance, `lambda x, y: x * y`

produces the same results as `lambda x, y: y * x`

.

However, this is not always the case. For some operations, the order does matter. In those instances, you must carefully distinguish between the accumulated value, which is the first argument, and the next iterator value, which is the second.

The next example shows a use case where the order of the arguments is important. It uses `reduce()`

to concatenate a list of words into a single string in reverse order.

**Example:**

from functools import reduce words = ["hello", "world", "python", "programming"] result = reduce(lambda x, y: y + " " + x, words) print(f"The concatenated string in reverse order is: {result}")

**Output:**

The concatenated string in reverse order is: programming python world hello

In the example above, the lambda function `lambda x, y: y + " " + x`

concatenates two words in reverse order. The accumulated value `x`

stores the previously concatenated words, and the next value `y`

is the next word from the iterator. In this operation, the order does matter. If we switch `x`

and `y`

by placing `x`

first and `y`

second, the words would not be reversed. The order of the arguments in the lambda function is crucial for building the string in reverse order.

## Built-In Functions

The `reduce()`

function is very powerful but not always necessary because Python does provide built-in implementations for some simple use-cases. For example, the `multiply()`

and `sum()`

functions will multiply and sum up iterables. There is no need to use `reduce()`

implementations of those as you’ve seen in this lesson. They were merely convenient illustrative examples. Additionally, the `join()`

function can join words into a single string, but it does not reverse them.

## Summary & Reference for the Python *reduce()* Function

The `reduce()`

function aggregates successive elements of an iterable using a function. It returns a single value representing the cumulative result of the operation.

The `reduce()`

function is in the `functools`

module and must be imported with an import statement such as `from functools import reduce`

.

The basic `reduce()`

function syntax involves passing a function, an iterable and an optional initial value: `reduce(function, iterable[, initializer])`

numbers = [2, 3, 4, 5] product = reduce(lambda x, y: x * y, numbers) # product --> 120

The `initializer`

argument is optional and provides an initial value for the cumulative operation. The initial value ensures that the `reduce()`

function will work in case the iterable it’s given is empty.

numbers = [] result = reduce(lambda x, y: x + y, numbers, 0) # result --> 0

The function passed to `reduce()`

accumulates values successively, with each iteration combining the result of the previous operation and the next element from the iterable. The first argument to the function is the accumulated value, and the second is the next value from the iterable. It returns the result of the operation.

def mult(x, y): print(f"Accumulated value: {x} Next value: {y}") return x * y

The `reduce()`

function is very powerful but not always necessary because Python provides built-in functions for some simple use-cases, such as `sum()`

, `multiply()`

and `join()`

.