itertools.accumulate() 与 functools.reduce() 的区别

31
在Python 3.3中,itertools.accumulate()通常会对提供的可迭代对象重复应用加法运算,现在可以接受一个函数参数作为参数; 这意味着它现在与functools.reduce()有一些重叠。初步看起来,两者之间的主要区别似乎是:
  1. accumulate()默认进行求和操作,但不允许您显式地提供额外的初始条件,而reduce()则不默认使用任何方法,但是会允许您提供一个初始条件,以供1 / 0元素序列使用。
  2. accumulate()首先接受可迭代对象,而reduce()首先接受函数。

这两个函数之间是否还有其他差异?还是说这只是两个最初具有不同用途的函数的行为开始趋于一致的问题?


1
accumulate执行扫描操作https://en.wikipedia.org/wiki/Prefix_sum,而reduce执行折叠操作https://en.wikipedia.org/wiki/Fold_(higher-order_function)。 - Yann Vernier
1
请注意,自Python 3.8以来,accumulate现在还具有可选的“initial”参数,因此这不再是两者之间的区别。 - Bill
3个回答

39

看起来accumulate会保留之前的结果,而reduce则不一定会。

例如,list(accumulate([1,2,3], operator.add))会返回[1,3,6],而普通的折叠会返回6

另外(只是为了好玩,不要这样做),你可以用reduce来定义accumulate

def accumulate(xs, f):
    return reduce(lambda a, x: a + [f(a[-1], x)], xs[1:], [xs[0]]) 

2
我猜你的意思是 operator.add。此外,我不知道最后一段代码是否真的有用:1)它返回一个列表而itertools.accumulate返回一个可迭代对象,2)它非常低效 :) - tokland
请查看此处以获取更好的实现。 - Mateen Ulhaq

9
您可以在文档中看到区别。 reduce 返回一个单一的结果,即序列的总和、积等。 accumulate 返回一个迭代器,其包含所有中间结果。基本上,accumulate 返回一个迭代器,其中包含reduce 操作每个步骤的结果。

7

itertools.accumulate类似于reduce,但返回的是一个生成器而不是一个值。这个生成器可以给你所有的中间步骤值。所以基本上,reduce会给你accumulate将要给你的最后一个元素。

* 生成器类似于迭代器,但只能迭代一次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接