reduce()有什么问题?


71

关于python 3.0中reduce()函数的更改以及如何删除它,网上似乎有很多热烈的讨论。我有点难以理解为什么会这样。我发现在各种情况下使用它是很合理的。如果蔑视仅仅是主观的,我无法想象会有这么多人关心它。

我想念什么?reduce()有什么问题?

Answers:


75

正如Guido在Python 3000帖子中的reduce()的命运中所说:

所以现在reduce()。实际上,这是我一直最讨厌的一个,因为,除了一些涉及+或*的示例,几乎每次我看到带有平凡函数参数的reduce()调用时,我都需要拿笔和纸来在我了解reduce()应该做什么之前,先绘制一下该函数实际输入的内容。因此,在我看来,reduce()的适用性几乎仅限于关联运算符,在所有其他情况下,最好显式地写出累加循环。

reduce在Functional Programming HOWTO文章中有一个很好的例子,令人困惑:

快速,以下代码在做什么?

total = reduce(lambda a, b: (0, a[1] + b[1]), items)[1]

您可以弄清楚,但是需要花一些时间来解开表达式以弄清楚发生了什么。使用简短的嵌套def语句会使事情变得更好一些:

def combine (a, b):
    return 0, a[1] + b[1]

total = reduce(combine, items)[1]

但是,如果我只是简单地使用for循环,那将是最好的:

total = 0
for a, b in items:
    total += b

或内置sum()和生成器表达式:

total = sum(b for a,b in items)

当将其作为for循环编写时,reduce()的许多用法会更清晰。


4
在这种情况下,它甚至更容易:求和(b为a,b为项)
— 约翰·米利金

28
化简代码不等于for循环。等效项如下: total = reduce(lambda total, (a,b): total + b, items, 0)
— 内森·希夫利·桑德斯

4
“ reduce函数可以混淆代码的意图。因此,应从语言中删除reduce。” 当然,我不知道谁是说正是这样,但它是一个不合逻辑的推论。
— Tony

2
要点,但公平地说,将lambda扔到您的示例中,相当于将血迹斑斑的衬衫交给警察阵容中的一个人。我不会说一开始reduce()不会引起混淆,但是functools中的所有内容都是在您启动时出现的。在学习使用functools的过程中,我发现它们越来越有用。现在,如果您想要令人困惑的示例,请查看itertools()。我也在学习也爱他们,但这是初次约会。:-)
— JS。

4
参数为“让我们采取行动,reduce因为它可用于编写不清楚的代码。” 好了,就可以**,+和-。我们应该将它们移动到functools吗?
— 埃里克·杜米尼尔

35

reduce()没有被删除-只是被移入functools模块中。Guido的推理是,除了诸如求和之类的琐碎情况外,使用编写的代码reduce()作为累加循环编写时通常更清晰。


34
Gah,这是可怕的理由:(
— TraumaPony

23
是吗?Python的大部分哲学都是关于编写清晰明了的代码。典型的reduce()调用通常需要我用一支铅笔来画图,并用函数来表示该函数。
— 约翰·米利金

31
除非您能证明我的性能有了显着提高(至少达到2倍),否则我每天都会对“表达的紧凑性”视而不见。
— 凯文·利特尔,

9

人们担心它会鼓励混淆的编程风格,而这样做却可以通过更清晰的方法来实现。

我不反对降低自己,有时我也发现它是一个有用的工具。


3

reduce的存在的主要原因是避免使用累加器显式地编写for循环。即使python具有支持功能样式的某些功能,也不鼓励使用。如果您喜欢“真实的”而不是“ pythonic”的功能风格,请使用现代的Lisp(Clojure?)或Haskel。


-1

使用霍纳方法使用reduce来计算多项式的值既紧凑又富有表现力。

计算x处的多项式值。a是多项式系数的数组

def poynomialValue(a,x):
   return reduce(lambda value, coef: value*x + coef, a)

这并不是在试图回答OP的问题。“为什么reduce有问题?” 答:“这是一个用例reduce”。
— ShadowRanger

这不能为问题提供答案。要批评或要求作者澄清,请在其帖子下方发表评论。-评分
— 阿里亚麦卡锡

强大的语言工具总是可以简化使用,但不够清晰。我想举一个例子,其中reduce可以用来紧凑地表达算法。请注意,这是一个非关联运算符的示例。
— user1153980
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.