12

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

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

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

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

这是一个丑陋的解决方案。有没有更蟒蛇的东西?

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

3 回答 3

16

我最喜欢的,如果你最近的话:

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]

累积也接受一个函数参数[甚至更近,虽然 - 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]
于 2012-09-02T06:06:12.623 回答
9

如果您为生成器制作解决方案,它会更短,并且更好地遵循函数式编程风格。我也会为 x 添加一个默认值 0:

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

那绝对是更蟒蛇

于 2012-09-02T06:14:35.500 回答
1

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

Python 有这个,它被称为累积,它在 Python 3.2 开始的 itertools 标准库模块中实现。可选的第二个参数“func”是在 3.3 中添加的。

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模块中定义的功能。您可以使用任何接受第一个参数中元素类型的 2 个参数的函数。您可以发挥创意,但在这里我将做相反的事情,并使用 lambda 显式实现默认的加法/求和行为:

import itertools

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

最后,既然你问了,我认为 usingaccumulate比你的循环示例更 Pythonic。

于 2018-09-20T07:41:45.783 回答