You know the handy reduce
function in Python. For example, you could use it to sum up a list like so (pretend there isn't the built-in sum):
reduce(lambda x,y: x+y, [1,2,3,4], 0)
which returns (((0+1)+2)+3)+4 = 10.
Now what if I wanted a list of the intermediate sums? In this case, [1,3,6,10]
.
Here's an ugly solution. Is there something more pythonic?
def reducelist(f, l, x):
out = [x]
prev = x
for i in l:
prev = f(prev, i)
out.append(prev)
return out
My favourite, if you're recent enough:
Python 3.2.1 (default, Jul 12 2011, 22:22:01)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import itertools
>>> itertools.accumulate([1,2,3,4])
<itertools.accumulate object at 0x1006baad0>
>>> list(itertools.accumulate([1,2,3,4]))
[1, 3, 6, 10]
accumulate also accepts a function argument [even more recent, though-- 3.3]:
>>> list(itertools.accumulate([1,2,3,4], lambda x,y: x+y))
[1, 3, 6, 10]
>>> list(itertools.accumulate([1,2,3,4], lambda x,y: x+y+1))
[1, 4, 8, 13]
If you make your solution to a generator it's shorter and it better obeys functional programming style. I would add an default value of 0 for x too:
def reducelist(f, lst, x=0):
prev = x
for i in lst:
prev = f(prev, i)
yield prev
That is definitely more pythonic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With