三参数的Reduce函数

22
在Python 3中,reduce函数如何使用三个参数而不是两个?对于两个参数的情况,它的工作方式为:
tup = (1,2,3)
reduce(lambda x, y: x+y, tup)

我理解这个问题。它只是将tup中所有元素相加。但是,如果您像下面这样给reduce函数三个参数,则不同:

tup = (1,2,3)
reduce(lambda x, y: x+y, tup, 6)

这将给你一个值为12的结果。我查阅了Python3的文档,它表示第三个参数是一个初始化器。那么,如果没有插入第三个参数,那默认的初始化器是什么?

3个回答

29
如果省略第三个参数,则使用 tup 的第一个值作为初始化器。换句话说,如果存在第二个参数,则 reduce() 将可选的第三个参数放置在其前面。此外,这意味着如果第二个参数是空序列,那么第三个参数将作为默认值,就像只有一个元素(没有显式的初始化器参数)的第二个参数一样是默认返回值。 functools.reduce() 文档 包括该函数的 Python 版本。
def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

请注意,当initializer不为None时,它将被用作第一个值,而不是从iterable中获取第一个值。


好的,我似乎明白了!这个函数中的 next 是什么作用? - chanpkr
1
@ChanPark:请查看next()函数文档;从迭代器中检索下一个值。如果iterable是元组,则是第一个索引。 - Martijn Pieters
1
请注意,实际的reduce函数确实接受 None 作为第三个参数。 - georg
@thg435:是的,在Python代码中,你可以使用一个哨兵; _sentinel = object(),然后在函数签名中使用initializer=_sentinel,接着使用if initializer is _sentinel:。但为了提高可读性,选择了None - Martijn Pieters

1

通过提供一个元组作为第三个参数,我们将能够在减少(reduce)的过程中计算并返回多个值。

from functools import reduce
def mean(my_list):                  # == sum(my_list) / len(my_list)
    return (lambda x: x[0]/x[1]) (reduce(lambda x, y : (x[0]+y, x[1]+1), 
                                                my_list, (0, 0,)))

5
可惜的是,由于强烈倾向于将其变成一行代码,这里的可读性有所降低。 - Abhijit Sarkar

0

reduce 可选的第三个参数:

>>> import functools
>>> test = []
>>> functools.reduce((lambda x,y: x+y), test, "testing")

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