# # Reduce

## # Overview

``````# No import needed

# No import required...
from functools import reduce # ... but it can be loaded from the functools module

from functools import reduce # mandatory

``````

`reduce` reduces an iterable by applying a function repeatedly on the next element of an `iterable` and the cumulative result so far.

``````def add(s1, s2):
return s1 + s2

asequence = [1, 2, 3]

# Out: 6

``````

In this example, we defined our own `add` function. However, Python comes with a standard equivalent function in the `operator` module:

``````import operator
# Out: 6

``````

`reduce` can also be passed a starting value:

``````reduce(add, asequence, 10)
# Out: 16

``````

## # Using reduce

``````def multiply(s1, s2):
print('{arg1} * {arg2} = {res}'.format(arg1=s1,
arg2=s2,
res=s1*s2))
return s1 * s2

asequence = [1, 2, 3]

``````

Given an `initializer` the function is started by applying it to the initializer and the first iterable element:

``````cumprod = reduce(multiply, asequence, 5)
# Out: 5 * 1 = 5
#      5 * 2 = 10
#      10 * 3 = 30
print(cumprod)
# Out: 30

``````

Without `initializer` parameter the `reduce` starts by applying the function to the first two list elements:

``````cumprod = reduce(multiply, asequence)
# Out: 1 * 2 = 2
#      2 * 3 = 6
print(cumprod)
# Out: 6

``````

## # Cumulative product

``````import operator
reduce(operator.mul, [10, 5, -3])
# Out: -150

``````

## # Non short-circuit variant of any/all

`reduce` will not terminate the iteration before the `iterable` has been completly iterated over so it can be used to create a non short-circuit `any()` or `all()` function:

``````import operator
# non short-circuit "all"
reduce(operator.and_, [False, True, True, True]) # = False

# non short-circuit "any"
reduce(operator.or_, [True, False, False, False]) # = True

``````

## # First truthy/falsy element of a sequence (or last element if there is none)

``````# First falsy element or last element if all are truthy:
reduce(lambda i, j: i and j, [100, [], 20, 10])    # = []
reduce(lambda i, j: i and j, [100, 50, 20, 10])    # = 10

# First truthy element or last element if all falsy:
reduce(lambda i, j: i or j, [100, [], 20, 0])     # = 100
reduce(lambda i, j: i or j, ['', {}, [], None])   # = None

``````

Instead of creating a `lambda`-function it is generally recommended to create a named function:

``````def do_or(i, j):
return i or j

def do_and(i, j):
return i and j

reduce(do_or, [100, [], 20, 0])                   # = 100
reduce(do_and, [100, [], 20, 0])                  # = []

``````

#### # Syntax

• reduce(function, iterable[, initializer])

#### # Parameters

Parameter Details
function function that is used for reducing the iterable (must take two arguments). (positional-only)
iterable iterable that's going to be reduced. (positional-only)
initializer start-value of the reduction. (optional, positional-only)

#### # Remarks

`reduce` might be not always the most efficient function. For some types there are equivalent functions or methods:

• `sum()` for the sum of a sequence containing **addable** elements (not strings):
``````sum([1,2,3])                                 # = 6

``````
• `str.join` for the concatenation of strings:
``````''.join(['Hello', ',', ' World'])            # = 'Hello, World'

``````
• `next` together with a generator could be a short-circuit variant compared to `reduce`:
``````# First falsy item:
next((i for i in [100, [], 20, 0] if not i)) # = []

``````