A call to functools.reduce
returns only the final result:
>>> from functools import reduce
>>> a = [1, 2, 3, 4, 5]
>>> f = lambda x, y: x + y
>>> reduce(f, a)
15
Instead of writing a loop myself, does a function exist which returns the intermediary values, too?
[3, 6, 10, 15]
(This is only a simple example, I'm not trying to calculate the cumulative sum - the solution should work for arbitrary a
and f
.)
You can use itertools.accumulate()
:
>>> from itertools import accumulate
>>> list(accumulate([1, 2, 3, 4, 5], lambda x, y: x+y))[1:]
[3, 6, 10, 15]
Note that the order of parameters is switched relative to functools.reduce()
.
Also, the default func
(the second parameter) is a sum (like operator.add
), so in your case, it's technically optional:
>>> list(accumulate([1, 2, 3, 4, 5]))[1:] # default func: sum
[3, 6, 10, 15]
And finally, it's worth noting that accumulate()
will include the first term in the sequence, hence why the result is indexed from [1:]
above.
In your edit, you noted that...
This is only a simple example, I'm not trying to calculate the cumulative sum - the solution should work for arbitrary a and f.
The nice thing about accumulate()
is that it is flexible about the callable it will take. It only demands a callable that is a function of two parameters.
For instance, builtin max()
satisfies that:
>>> list(accumulate([1, 10, 4, 2, 17], max))
[1, 10, 10, 10, 17]
This is a longer form of using the unnecessary lambda:
>>> # Don't do this
>>> list(accumulate([1, 10, 4, 2, 17], lambda x, y: max(x, y)))
[1, 10, 10, 10, 17]