Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reducelist in Python: like reduce but giving the list of intermediate results

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
like image 921
dreeves Avatar asked Sep 02 '12 06:09

dreeves


2 Answers

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]
like image 69
DSM Avatar answered Oct 12 '22 11:10

DSM


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.

like image 40
halex Avatar answered Oct 12 '22 12:10

halex