Today we’ll be talking about the accumulate function from the itertools module. The itertools module contains quite a few interesting methods that we can use to work on iterators. These functions take iterables as arguments and return iterators.
If you want to learn more about iterators and iterables, I have an article about them, so feel free to read it.
One of the functions is accumulate. It returns series of accumulated results. We can determine how the results are to be accumulated. By default they’re accumulated as sums. This is what happens if we pass just one argument to the function, the iterable.
The function returns an iterator, which means you can retrieve the elements one by one using the next function. You can also use a for loop to retrieve all the items.
You can also retrieve all elements at once by converting the iterator to a list. And this is what we’re going to do in our examples.
Table of Contents
Accumulative Addition
So, let’s have our first example.
First of all, we have to import the accumulate function from the itertools module:
>>> from itertools import accumulate
Now let’s create a simple iterable, like a list:
>>> nums = [1, 2, 3, 4, 5]
Now we can use the accumulate function:
>>> a = list(accumulate(nums))
>>> a
[1, 3, 6, 10, 15]
What the function does is take the first element in nums, then the sum of the first and second element, then the sum of this and the third element, and so on.
Example: Accumulated Income
Let’s have a more practical example. Suppose you have a business and want to know your accumulated income at the end of each month throughout the whole year. You can easily do it like so:
from itertools import accumulate
months = {'January': 2000,
'February': 2200,
'March': 2500,
'April': 3100,
'May': 3000,
'June': 2700,
'July': 3100,
'August': 3300,
'September': 5400,
'October': 4200,
'November': 4500,
'December': 3900}
accumulated = accumulate(months.values())
for month, acc in zip(months, accumulated):
print(f"earned in {month}: ${months[month]}, ${acc} since the beginning of the year")
Here’s the output:
earned in January: $2000, $2000 since the beginning of the year
earned in February: $2200, $4200 since the beginning of the year
earned in March: $2500, $6700 since the beginning of the year
earned in April: $3100, $9800 since the beginning of the year
earned in May: $3000, $12800 since the beginning of the year
earned in June: $2700, $15500 since the beginning of the year
earned in July: $3100, $18600 since the beginning of the year
earned in August: $3300, $21900 since the beginning of the year
earned in September: $5400, $27300 since the beginning of the year
earned in October: $4200, $31500 since the beginning of the year
earned in November: $4500, $36000 since the beginning of the year
earned in December: $3900, $39900 since the beginning of the year
Accumulative Multiplication
As mentioned above, the default behavior is addition. This is because the optional func parameter of the accumulate function is by default set to operator.add.
We can also use other operators or functions as the second argument. In order to use other operators, we have to import the operator module. Let’s now multiply the numbers accumulatively instead of summing them:
>>> from itertools import accumulate
>>> import operator
>>>
>>> nums = [1, 2, 3, 4, 5]
>>> a = list(accumulate(nums, operator.mul))
>>> a
[1, 2, 6, 24, 120]
And here’s a more practical example: A company ships buttons in trucks. They put 20 buttons in a bag, 10 bags in a box, 50 boxes on a pallet, 12 pallets in a truck. We can check the number of buttons in each of the containers. Have a look:
from itertools import accumulate
import operator
containers = {'buttons_in_bag': 20,
'bags_in_box': 10,
'boxes_on_pallet': 50,
'pallets_in_truck': 12}
accumulated = accumulate(containers.values(), operator.mul)
for cont, acc in zip(containers, accumulated):
container = cont.split('_')[-1] # the last part of the key (bag, box, etc.)
print(f"There are {acc} buttons in a {container}.")
Now you will see this:
There are 20 buttons in a bag.
There are 200 buttons in a box.
There are 10000 buttons in a pallet.
There are 120000 buttons in a truck.
Accumulation with the max Function
Now let’s use the built-in max function as the second argument to the accumulate function. This time the accumulated value will be equal to the maximum value so far.
And now an example where we want to introduce people one by one and after introducing each person we want to know the maximum age so far.
Here’s the code:
from itertools import accumulate
people = {'Bill': 21,
'Joe': 24,
'Steve': 20,
'Mary': 19,
'Cindy': 26,
'Jane': 21,
'Luke': 23}
accumulated = accumulate(people.values(), max)
for person, acc in zip(people, accumulated):
print(f"Here's {person}, aged {people[person]}. The oldest person so far is {acc} years old.")
And here’s the output:
Here's Bill, aged 21. The oldest person so far is 21 years old.
Here's Joe, aged 24. The oldest person so far is 24 years old.
Here's Steve, aged 20. The oldest person so far is 24 years old.
Here's Mary, aged 19. The oldest person so far is 24 years old.
Here's Cindy, aged 26. The oldest person so far is 26 years old.
Here's Jane, aged 21. The oldest person so far is 26 years old.
Here's Luke, aged 23. The oldest person so far is 26 years old.
Here’s the video version of the article: