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

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-04 03:00:16

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.

Note: Somehow I missed @DSM's answer before I wrote this. Go read and up vote that one instead, I just did. Come back if you want a longer answer.

Python has this, it's called accumulate and it's implemented in the itertools standard library module starting in Python 3.2. The optional second argument, 'func', was added in 3.3.

import itertools

l = [1,2,3,4]
out = itertools.accumulate(l)

In this case out is an iterable. If you need a list, then

out = list(itertools.accumulate(l))

The accumulate() function can be used to generate a running total, or 'accumulated sums'. The default function is addition. We can pass in a function as the second argument:

import itertools
import operator

l = [1,2,3,4]
factorial = itertools.accumulate(l, operator.mul)

Here we pass in operator.mul for multiplication to generate a running product. The operator module exports a set of efficient functions corresponding to the intrinsic operators of Python.

Of course we're not limited to functions defined in the operator module. You can use any function that accepts 2 parameters of the type of the elements in the first parameter. You can get creative, but here I'll do the opposite and explicitly implement the default addition/sum behavior using a lambda:

import itertools

l = [1,2,3,4]
out = itertools.accumulate(l, lambda a, b: a + b)

Finally, since you asked, I think using accumulate is more Pythonic then your looping example.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!