Python reduce and accumulate total guide
Python reduce function
Python’s reduce() implements a mathematical technique commonly known as folding or reduction. You’re doing a fold or reduction when you reduce a list of items to a single cumulative value. Python’s reduce() operates on any iterable (not just lists) and performs the following steps:
Apply a function
(or callable) to the first two items (default) in an iterable and generate a partial result.Use that partial result
, together with the third item in the iterable, to generate another partial result.Repeat the process
until the iterable is exhausted and then return a single cumulative value.
Python reduce function
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.[python doc]
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
The idea behind Python’s reduce() is to take an existing function, apply it cumulatively to all the items in an iterable, and generate a single final value. In general, Python’s reduce() is handy for processing iterables without writing explicit for loops. Since reduce() is written in C, its internal loop can be faster than an explicit Python for loop.
Python’s reduce() was originally a built-in function (and still is in Python 2.X ), but it was moved to functools.reduce() in Python 3.0 . This decision was based on some possible performance and readability issues.
In Python 3.X, if you need to use reduce(), then you first have to import the function into your current scope using an import statement in one of the following ways:
- import functools and then use fully-qualified names like functools.reduce().
- from functools import reduce and then call reduce() directly.
functools.reduce(function, iterable[, initializer])
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.
find sum of iterable int with reduce
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
# output
# 15
Find the largest number in the iterable using reduce()
from functools import reduce
num1 = [15,12,30,4,5]
num2 = reduce(lambda x,y: x if x>y else y, num1)
print(num2)
# output
# 30
Using User-defined function in reduce()
from functools import reduce
def my_add(a, b):
result = a + b
print(f"{a} + {b} = {result}")
return result
numbers = [0, 1, 2, 3, 4]
reduce(my_add, numbers)
# output:
# 0 + 1 = 1
# 1 + 2 = 3
# 3 + 3 = 6
# 6 + 4 = 10
# 10
Iterable contains only one item, reduce() will return that item.
from functools import reduce
def sum1(x, y):
return x + y
num1 = [5]
num2 = reduce(sum1,num1)
print(num2)
# output
# 5
from functools import reduce
num1 = [15]
num2 = reduce(lambda x,y: x if x>y else y, num1)
print(num2)
# output
# 15
python reduce initializer
functools.reduce(function, iterable[, initializer])
Initializer
The third argument to Python’s reduce(), calledinitializer
, is optional. If you supply a value to initializer, then reduce() will feed it to the first call of function as its first argument. This means that the first call to function will use the value of initializer
and the first item of iterable to perform its first partial computation. After this, reduce() continues working with the subsequent items of iterable.
from functools import reduce
def my_add(a, b):
result = a + b
print(f"{a} + {b} = {result}")
return result
numbers = [0, 1, 2, 3, 4]
reduce(my_add, numbers, 100)
# output
# 100 + 0 = 100
# 100 + 1 = 101
# 101 + 2 = 103
# 103 + 3 = 106
# 106 + 4 = 110
# 110
Python accumulate function
itertools.accumulate(iterable[, func, *, initial=None])
Python accumulate
Make an iterator that returns accumulated sums, or accumulated results of other binary functions (function with exactly two inputs) specified via the optional func argument.
If func is supplied, it should be a function of two arguments. Elements of the input iterable may be any type that can be accepted as arguments to func. You can use predefined python standard operators as functions .
The first value in the iterator returned by python accumulate() is always the first value in the input sequence.
Usually, the number of elements output matches the input iterable. However, if the keyword argument initial is provided, the accumulation leads off with the initial value so that the output has one more element than the input iterable.
def accumulate(inputs, func):
itr = iter(inputs)
prev = next(itr)
for cur in itr:
yield prev
prev = func(prev, cur)
Multiple list items
The function argument is given as operator.mul .
operator.mul(a, b)
operator.__mul__(a, b)
Return a * b, for a and b numbers.
It will return an iterator that yields all intermediate values. We can convert to list by using a list() constructor.
from itertools import accumulate
import operator
num = accumulate([1,2,3,4,5], operator.mul)
print (list(num))
# output
# [1, 2, 6, 24, 120]
accumulate pictorial representation:
default func parameter
It will return an iterator that yields all intermediate values. We can convert to a list by using list() constructor.
import itertools
num = itertools.accumulate([1,2,3,4,5])
print(num)
# output
# <itertools.accumulate object at 0x7f218a1e6bc0>
# convert iterator to list object
print(list(num))
# output
# [1, 3, 6, 10, 15]
# using reduce() for same function
from functools import reduce
import operator
r = reduce(operator.add, [1,2,3,4,5])
print(r)
# output:
# 15
own defined function
import itertools
def sum_numbers( *args):
return sum(args)
sum_numbers(1, 2, 3, 4)
# output:
# 10
list(itertools.accumulate([1,2,3,4,5], sum_numbers))
# output:
# [1, 3, 6, 10, 15]
accumulate initial value
from itertools import accumulate
import operator
# it will contain more than one element in the ouptut iterable.
num = accumulate([1,2,3,4,5], operator.add, initial=10)
print(list(num))
# output:
# [10, 11, 13, 16, 20, 25]
If the iterable is empty and the initial parameter is mentioned, it will return the initial value.
from itertools import accumulate
import operator
num = accumulate([], operator.add, initial=10)
print(list(num))
# output:
# [10]
If iterable contains one element and the initial parameter is not mentioned, it will return that element.
from itertools import accumulate
num = accumulate([5], lambda x,y: x+y)
print(list(num))
# output:
# [5]