10.3. FP Apply Reduce
10.3.1. About
Reduce sequence using function
Built-in
In Python, reduce() is a built-in function that applies a given function
to the elements of an iterable (e.g. a list, tuple, or set) and returns a
single value. The function takes two arguments: the first is the function to
apply, and the second is the iterable to be processed.
The reduce() function works by applying the function to the first two
elements of the iterable, then to the result and the next element, and so
on, until all elements have been processed and a single value is obtained.
10.3.2. Example
functools.reduce(function, iterable[, initializer])required
callable- Functionrequired
iterable- Sequence or iterator object
Here's an example:
>>> from functools import reduce
>>>
>>> # Define a list of numbers
>>> numbers = [1, 2, 3, 4, 5]
>>>
>>> # Use reduce() to sum the numbers
>>> result = reduce(lambda x,y: x+y, numbers)
>>>
>>> print(result)
15
In this example, the reduce() function applies the lambda function
(which adds two numbers) to the elements of the numbers list, resulting
in the sum of all the numbers.
10.3.3. SetUp
>>> from functools import reduce
10.3.4. Problem
>>> def add(x, y):
... return x + y
>>>
>>>
>>> DATA = [1, 2, 3, 4]
>>> result = 0
>>>
>>> for element in DATA:
... result = add(result, element)
>>>
>>> print(result)
10
10.3.5. Solution
>>> DATA = [1, 2, 3, 4]
>>>
>>>
>>> def add(x, y):
... return x + y
>>>
>>> reduce(add, DATA)
10
10.3.6. Rationale
The operator module in Python provides a set of functions that implement
common operations on Python objects, such as arithmetic operations,
comparisons, and logical operations. These functions are designed to be used
as functional arguments to other functions, such as map(), filter(),
and reduce().
The operator module provides functions for arithmetic operations such as
addition, subtraction, multiplication, division, and exponentiation. It also
provides functions for bitwise operations, such as bitwise AND, OR, XOR, and
shift operations.
In addition to arithmetic and bitwise operations, the operator module
provides functions for comparisons, such as greater than, less than, equal
to, and not equal to. It also provides functions for logical operations,
such as not, and, and or.
Here's an example of using the operator module to sort a list of tuples
based on the second element of each tuple:
>>> import operator
>>>
>>> # Define a list of tuples
>>> data = [(2, 'b'), (1, 'a'), (3, 'c')]
>>>
>>> # Sort the list based on the second element of each tuple
>>> sorted_data = sorted(data, key=operator.itemgetter(1))
>>>
>>> print(sorted_data)
[(1, 'a'), (2, 'b'), (3, 'c')]
In this example, the itemgetter() function from the operator module
is used as the key argument to the sorted() function. This function
returns a callable that extracts the second element of each tuple, which is
used to sort the list.
>>> DATA = [1, 2, 3, 4]
>>>
>>> from operator import mul
>>> reduce(mul, DATA)
24
>>> def add(a, b):
... print(f'{a=}, {b=}')
... return a + b
>>>
>>>
>>> data = [1, 2, 3, 4]
>>> reduce(add, data)
a=1, b=2
a=3, b=3
a=6, b=4
10
10.3.7. Use Case - 1
>>> from functools import reduce
>>>
>>>
>>> def square(x):
... return x ** 2
>>>
>>> def cube(x):
... return x ** 3
>>>
>>> def increment(x):
... return x + 1
>>>
>>> def decrement(x):
... return x - 1
>>>
>>> def even(x):
... return x % 2 == 0
>>>
>>> def gt10(x):
... return x > 10
>>>
>>> def add(a, b):
... return a + b
>>>
>>>
>>> data = (1, 2, 3, 4, 5)
>>>
>>> incremented = map(increment, data)
>>> squared = map(square, incremented)
>>> filtered = filter(even, squared)
>>> decremented = map(decrement, filtered)
>>> final = filter(gt10, decremented)
>>> result = reduce(add, final)
>>>
>>> print(result)
50
10.3.8. Use Case - 2
>>> from functools import reduce
>>>
>>>
>>> def add(x, y):
... return x + y
>>>
>>> def sub(x, y):
... return x - y
>>>
>>> def mul(x, y):
... return x * y
>>>
>>>
>>> data = (1, 2, 3, 4)
>>>
>>> reduce(add, data)
10
>>> reduce(sub, data)
-8
>>> reduce(mul, data)
24
10.3.9. Use Case - 3
>>> from functools import reduce
>>>
>>>
>>> data = (1, 2, 3, 4)
>>>
>>> reduce(lambda x,y: x+y, data)
10
>>> reduce(lambda x,y: x-y, data)
-8
>>> reduce(lambda x,y: x*y, data)
24
10.3.10. Use Case - 4
>>> from functools import reduce
>>> from operator import add, sub, mul
>>>
>>>
>>> data = (1, 2, 3, 4)
>>>
>>> reduce(add, data)
10
>>> reduce(sub, data)
-8
>>> reduce(mul, data)
24
10.3.11. Use Case - 5
Iterative approach:
>>> data = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>>
>>> result = 0
>>>
>>> for row in data:
... for digit in row:
... result += digit
>>>
>>> print(result)
45
Functional approach:
>>> from functools import reduce
>>> from operator import add
>>>
>>>
>>> data = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
>>>
>>> result = reduce(add, (
... reduce(add, data[0]),
... reduce(add, data[1]),
... reduce(add, data[2]),
... ))
>>>
>>> print(result)
45
10.3.12. Use Case - 6
>>> from functools import reduce
>>> from itertools import starmap
>>> from operator import add, sub, mul
>>> def square(x):
... return x ** 2
>>>
>>> def cube(x):
... return x ** 3
>>>
>>> def apply(data, fn):
... return map(fn, data)
>>> data = (1, 2, 3, 4)
>>> funcs = (square, cube)
>>>
>>> result = reduce(apply, funcs, data)
>>> tuple(result)
(1, 64, 729, 4096)
>>>
>>> result = reduce(apply, funcs, data)
>>> reduce(add, result)
4890
>>> data = (1, 2, 3, 4)
>>> funcs = (add, sub, mul)
>>>
>>> result = map(lambda fn: reduce(fn,data), funcs)
>>> reduce(add, result)
26
>>> funcs = (
... (add, data),
... (sub, data),
... (mul, data),
... )
>>>
>>> data = (1, 2, 3, 4)
>>> result = starmap(reduce, funcs)
>>> reduce(add, result)
26
>>> result = starmap(reduce, (
... (add, data),
... (sub, data),
... (mul, data),
... ))
>>>
>>> data = (1, 2, 3, 4)
>>> reduce(add, result)
26
10.3.13. Use Case - 7
split-apply-combine strategy
Apply function of two arguments cumulatively to the items of iterable, from
left to right, so as to reduce the iterable to a single value. For example,
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and
the right argument, y, is the update value from the iterable. If the
optional initializer is present, it is placed before the items of the
iterable in the calculation, and serves as a default when the iterable is
empty. If initializer is not given and iterable contains only one item, the
first item is returned.
Roughly equivalent to:
>>> def reduce(function, iterable, initializer=None):
... it = iter(iterable)
... if initializer is None:
... value = next(it)
... else:
... value = initializer
... for element in it:
... value = function(value, element)
... return value
SetUp:
>>> from functools import reduce
>>>
>>> DATA = (1, 2, 3, 4, 5)
Usage:
>>> def add(a, b):
... return a + b
>>>
>>> reduce(add, DATA)
15
>>> reduce(lambda x,y: x+y, DATA)
15
10.3.14. Use Case - 8
>>> from functools import reduce
>>>
>>>
>>> def square(x):
... return x ** 2
>>>
>>> def cube(x):
... return x ** 3
>>>
>>> def apply(data, fn):
... return map(fn, data)
>>>
>>> def add(x, y):
... return x + y
>>>
>>>
>>> data = (1, 2, 3, 4)
>>> transformations = (square, cube)
>>>
>>> transformed = reduce(apply, transformations, data) # (1, 64, 729, 4096)
>>> result = reduce(add, transformed)
>>>
>>> print(result)
4890
10.3.15. Assignments
# %% About
# - Name: Functional Reduce DefAdd
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Reduce `DATA` to calculate sum of its elements
# 2. Define function `add(x: int, y: int) -> int` that returns sum of `x` and `y`
# 3. Use `functools.reduce()`
# 4. Define variable `result` with the solution
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zredukuj `DATA` aby obliczyć sumę jego elementów
# 2. Zdefiniuj funkcję `add(x: int, y: int) -> int`, która zwraca sumę `x` i `y`
# 3. Użyj `functools.reduce()`
# 4. Zdefiniuj zmienną `result` z rozwiązaniem
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - `reduce(callable, iterable)`
# - `def myfunc(): ...`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert 'add' in globals(), \
'Function `add` is not defined; define it before using.'
>>> assert isfunction(add), \
'Object `add` has an invalid type; expected `function`.'
>>> assert 'result' in globals(), \
'Variable `result` is not defined; assign result of your program to it.'
>>> assert result is not Ellipsis, \
'Variable `result` has an invalid value; assign result of your program to it.'
>>> assert type(result) is int, \
'Variable `result` has an invalid type; expected: `int`.'
>>> result
15
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
from functools import reduce
# %% Types
result: int
# %% Data
def add(x, y):
return x + y
DATA = (1, 2, 3, 4, 5)
# %% Result
result = ...
# %% About
# - Name: Functional Reduce OperatorAdd
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Reduce `DATA` to calculate sum of its elements
# 2. Use `operator.add()`
# 3. Use `functools.reduce()`
# 4. Define variable `result` with the solution
# 5. Run doctests - all must succeed
# %% Polish
# 1. Zredukuj `DATA` używając funkcji `add()` aby obliczyć sumę jego elementów
# 4. Użyj `operator.add()`
# 3. Użyj `functools.reduce()`
# 4. Zdefiniuj zmienną `result` z rozwiązaniem
# 5. Uruchom doctesty - wszystkie muszą się powieść
# %% Hints
# - `reduce(callable, iterable)`
# - `operator.add()`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert 'add' in globals(), \
'Function `add` is not defined; define it before using.'
>>> assert isfunction(add), \
'Object `add` has an invalid type; expected `function`.'
>>> assert 'result' in globals(), \
'Variable `result` is not defined; assign result of your program to it.'
>>> assert result is not Ellipsis, \
'Variable `result` has an invalid value; assign result of your program to it.'
>>> assert type(result) is int, \
'Variable `result` has an invalid type; expected: `int`.'
>>> result
15
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
from functools import reduce
# %% Types
result: int
# %% Data
def add(x, y):
return x + y
DATA = (1, 2, 3, 4, 5)
# %% Result
result = ...