我试图理解以下代码:
>>> print(reduce(lambda x, y: x + y, [1,2,3,4,5]))
15
什么是
x
和y
?这里的累加器是哪个?累加器是否始终必须是第一个参数(即此处的 x
)
如果没有进行初始化会发生什么?选择的默认值是多少?
我认为 functools.reduce(function, iterable[,initializer]) 的文档非常可读。执行迭代,从左到右对连续元素应用运算并将结果累加到左操作数中。为了确定所讨论的方面,它有助于创建上述代码的变体。
在下面的例子中,我们得到元素的和;我们看到,工作中没有隐式
1
作为“默认”值:
>>> print(reduce(lambda x, y: x + y, [2,3]))
5
如果迭代中没有剩余元素,则缩减停止:
>>> print(reduce(lambda x, y: x + y, [1]))
1
如果根本没有元素,则减少失败:
>>> print(reduce(lambda x, y: x + y, []))
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
print(reduce(lambda x, y: x + y, []))
TypeError: reduce() of empty sequence with no initial value
可选的
initializer
值用于启动缩减(如果没有元素则立即停止):
>>> print(reduce(lambda x, y: x + y, [], 0))
0
所以
x
确实是在进入可迭代之前用可选的 initializer
值初始化的累加器。并且 y
是可迭代的下一个值,如果没有元素(左侧),则 function
将被忽略。
这里是另一个例子,可以更好地理解
x
和 y
的作用:
>>> print(reduce(lambda x, y: x - y, [1,2,3], 10))
4
在单步模式下,上面的缩减看起来像这样:
x = 10 # initializer
y = 1 # from iterable
x = x-y # x==9
y = 2 # from iterable
x = x-y # x==7
y = 3 # from iterable
x = x-y # x==4
4 # result
此代码的扩展形式可能更容易理解
lst = [1, 2, 3, 4, 5]
x = 0 # Default value
for i in lst:
y = i
x = x + y
print(x)
或者,如果考虑 lambda 函数:
lst = [1, 2, 3, 4, 5]
x = 0
def func(x,y):
x = x + y
return x
for i in lst:
x = func(x, i)
print(x)
如你所见,
x
是这里的累加器。如果不将累加器指定为第一个参数,您将无法使用 reduce
方法。
希望能够弄清楚您的代码是如何工作的。
更新:正如@Wolf 指出的,我们可以为reduce 方法的args 指定一个初始值。将
x
更新为 0,因为这是默认值。