What would be the Pythonic way of performing a reduce with accumulation?
For example, take R
\'s Reduce(). Given a list and an arbitrary lambda function
In Python 3 (introduced in 3.2, ability to pass the function added in 3.3) this is already implemented, in itertools.accumulate. Just use it like this:
from itertools import accumulate
list(accumulate([5, 4, 3, 2], lambda a, b: a*b))
# [5, 20, 60, 120]
If you are using an earlier Python version, or want to implement it yourself, and you really want any arbitrary lambda
(that takes two arguments) to work, then you could use the generator which is given in the documentation of the above:
def accumulate(iterable, func=operator.add):
'Return running totals'
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable)
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = func(total, element)
yield total
The usage is exactly the same as above.
If you are using numpy
, then there exists a faster solution, at least for all numpy.ufunc
s. These include basically the same functions that the standard library module math
provides, and then some. You can find a complete list here.
Every numpy.ufunc
has the accumulate method, so you can just do:
import numpy as np
np.multiply.accumulate([5, 4, 3, 2])
# array([ 5, 20, 60, 120])