目前网络上有很多关于Python 3.0中reduce()函数的变化以及为什么应该将其删除的激烈讨论。我有些难以理解为什么会有这种情况,因为我觉得在各种情况下使用它都是相当合理的。如果人们的厌恶只是主观的,我无法想象会有如此多的人关心它。
那我错过了什么?reduce()函数的问题是什么?
目前网络上有很多关于Python 3.0中reduce()函数的变化以及为什么应该将其删除的激烈讨论。我有些难以理解为什么会有这种情况,因为我觉得在各种情况下使用它都是相当合理的。如果人们的厌恶只是主观的,我无法想象会有如此多的人关心它。
那我错过了什么?reduce()函数的问题是什么?
正如Guido在他的Python 3000中reduce()的命运文章中所说:
现在考虑reduce()。实际上这是我一直最讨厌的一个,因为除了涉及 + 或 * 的一些示例之外,几乎每次我看到使用非平凡函数参数的reduce()调用时,都需要拿起笔和纸来绘制出实际被馈送到该函数中的东西,然后才能理解reduce()应该做什么。因此,在我看来,reduce()的适用性基本上局限于关联运算符,在所有其他情况下,最好明确地编写累加循环。
函数式编程HOWTO文章中有一个极具困惑性的reduce()的优秀示例:
Quick, what's the following code doing?
total = reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
You can figure it out, but it takes time to disentangle the expression to figure out what's going on. Using a short nested def statements makes things a little bit better:
def combine (a, b): return 0, a[1] + b[1] total = reduce(combine, items)[1]
But it would be best of all if I had simply used a for loop:
total = 0 for a, b in items: total += b
Or the sum() built-in and a generator expression:
total = sum(b for a,b in items)
Many uses of reduce() are clearer when written as for loops.
reduce()
函数并没有被删除,而是被移动到了 functools
模块中。Guido 的想法是,除了像求和这样的简单情况之外,使用 reduce()
编写的代码通常在写为累积循环时更加清晰易懂。
有人担心它会鼓励一种模糊的编程风格,而这种效果可以通过更清晰的方法实现。
我个人并不反对使用reduce,有时候我也觉得它是一个有用的工具。
reduce的主要存在原因是为了避免使用累加器显式编写for循环。虽然Python有一些支持函数式风格的工具,但并不鼓励使用。如果你喜欢“真正”的而非“Python式”的函数式风格,请使用现代 Lisp(Clojure?)或Haskell。
(0, acc)
作为累加器)。我目前的用例是计算a ++ b ++ c ++ d ++ e
,而无需创建T中的“零”,也无需混乱地处理“半个循环逻辑”(acc = loop[0]; for x in loop[1:]: acc = acc ++ x
)。 - Att Righ使用reduce函数结合霍纳法则计算多项式值既紧凑又富有表现力。
在x处计算多项式值。 a是多项式的系数数组。
def poynomialValue(a,x):
return reduce(lambda value, coef: value*x + coef, a)
reduce
是个问题?" 答案是:"这里有一个使用reduce
的案例。" - ShadowRangerreduce
永远不能被清晰地使用,甚至也没有人说它不适用的例子很多。问题是它有什么问题,而不是它有什么优点。反对reduce
的观点是它容易被误用,影响可读性,并且不符合Python的非函数式编程方向。这些是回答OP关于为什么将其降级到functools
的可能答案。 - ggorlen
total = reduce(lambda total, (a,b): total + b, items, 0)
- Nathan Shively-Sandersreduce
,因为它可能用于编写不清晰的代码。” 嗯,**
、+
和-
也可以写不清晰的代码。那我们是否应该将它们移到functools
中? - Eric Duminil