Python中的reducelist:比如reduce,但给出了中间结果列表

时间:2012-09-02 06:01:14

标签: python list functional-programming reduce

你知道Python中的方便reduce函数。例如,您可以使用它来总结这样的列表(假装没有内置的sum):

reduce(lambda x,y: x+y, [1,2,3,4], 0)

返回(((0 + 1)+2)+3)+4 = 10.

现在如果我想要一个中间总和列表怎么办?在这种情况下,[1,3,6,10]

这是一个丑陋的解决方案。还有更多的pythonic吗?

def reducelist(f, l, x): 
  out = [x]
  prev = x
  for i in l:
    prev = f(prev, i)
    out.append(prev)
  return out

3 个答案:

答案 0 :(得分:14)

我最喜欢的,如果你已经足够了:

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也接受函数参数[更近期,但是 - 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]

答案 1 :(得分:8)

如果你使用生成器来解决它的问题,它会更短,并且更好地遵循函数式编程风格。我也会为x添加默认值0:

def reducelist(f, lst, x=0): 
  prev = x
  for i in lst: 
    prev = f(prev, i)
    yield prev

这绝对是 pythonic

答案 2 :(得分:1)

注意:在写这篇文章之前,我不知何故错过了@DSM的答案。去读一读,我刚做了。如果您想要更长的答案,请回来。

Python拥有此功能,它称为累加(accumulate),并从Python 3.2开始在itertools标准库模块中实现。在3.3中添加了可选的第二个参数'func'。

import itertools

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

在这种情况下,out是可迭代的。如果您需要列表,那么

out = list(itertools.accumulate(l))

accumulate()函数可用于生成运行总计或“累计总和”。默认功能是加法。我们可以传入一个函数作为第二个参数:

import itertools
import operator

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

在这里,我们传入operator.mul进行乘法运算以生成正在运行的乘积。 operator模块导出一组与Python的内在运算符相对应的有效函数。

我们当然不限于在operator模块中定义的函数。您可以使用任何在第一个参数中接受两个元素类型的参数的函数。您可以发挥创造力,但是在这里我将做相反的事情,并使用lambda显式实现默认的加/和行为:

import itertools

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

最后,如您所问,我认为使用accumulate比使用循环示例更适合Python。