Cumulative Calculations in Python: itertools.accumulate()

Modified: | Tags: Python

In Python, the itertools.accumulate() function allows you to apply any function cumulatively. For example, it is used to calculate the cumulative sum and product of a list.

You can also calculate cumulative sums and products using functions and methods in NumPy and pandas. Refer to the following articles for details.

Basic usage of itertools.accumulate()

By default, itertools.accumulate() creates an iterator that returns cumulative sums.

It takes an iterable object like a list or tuple as an argument. Since it returns an iterator, the results are not directly displayed with print().

import itertools

l = [1, 2, 3, 4, 5, 6]

print(itertools.accumulate(l))
# <itertools.accumulate object at 0x1080e1a80>

print(type(itertools.accumulate(l)))
# <class 'itertools.accumulate'>

You can obtain the results sequentially using a for loop.

for i in itertools.accumulate(l):
    print(i)
# 1
# 3
# 6
# 10
# 15
# 21

To get the result as a list, use list(). For a tuple, use tuple().

print(list(itertools.accumulate(l)))
# [1, 3, 6, 10, 15, 21]

To include a 0 value at the beginning, concatenate with [0]. Alternatively, use the initial argument, explained later (available in Python 3.8 and later).

print([0] + list(itertools.accumulate(l)))
# [0, 1, 3, 6, 10, 15, 21]

To calculate a cumulative sum in reverse order, reverse the original list using reversed().

print(list(itertools.accumulate(reversed(l))))
# [6, 11, 15, 18, 20, 21]

Specify the function to apply cumulatively: func

Use the func argument to specify a function to apply cumulatively to the elements. By default, it is addition, which calculates a cumulative sum as shown in the previous section.

For example, specifying operator.mul() as the func argument calculates a cumulative product. Note that when specifying a callable object like a function, do not add parentheses ().

import itertools
import operator

print(operator.mul(2, 3))
# 6

l = [1, 2, 3, 4, 5, 6]

print(list(itertools.accumulate(l, func=operator.mul)))
# [1, 2, 6, 24, 120, 720]

The operator module provides functions corresponding to operators like + and *.

Besides addition (cumulative sum) and multiplication (cumulative product), you can also apply subtraction and division cumulatively.

print(list(itertools.accumulate(l, func=operator.sub)))
# [1, -1, -4, -8, -13, -19]

print(list(itertools.accumulate(l, func=operator.truediv)))
# [1, 0.5, 0.16666666666666666, 0.041666666666666664, 0.008333333333333333, 0.001388888888888889]

Any function that takes two arguments can be used.

print(list(itertools.accumulate([1, 3, 2, 6, 5, 4], func=max)))
# [1, 3, 3, 6, 6, 6]

Lambda expressions can also be used. You can apply any process you want.

print(list(itertools.accumulate(l, func=lambda x, y: x * y)))
# [1, 2, 6, 24, 120, 720]

print(list(itertools.accumulate(l, func=lambda x, y: int(str(x) + str(y)))))
# [1, 12, 123, 1234, 12345, 123456]

The first example is equivalent to using operator.mul(). In the second example, numbers are converted to strings, concatenated, and then converted back to integers.

Specify the initial value: initial

From Python 3.8 onwards, you can specify an initial value using the initial argument.

Specifying a value for initial treats it as the first element, thus increasing the result's element count by one. The default is initial=None.

import itertools

l = [1, 2, 3, 4, 5, 6]

print(list(itertools.accumulate(l)))
# [1, 3, 6, 10, 15, 21]

print(list(itertools.accumulate(l, initial=0)))
# [0, 1, 3, 6, 10, 15, 21]

print(list(itertools.accumulate(l, initial=100)))
# [100, 101, 103, 106, 110, 115, 121]

Related Categories

Related Articles