reduce函数是如何工作的?

44 投票
9 回答
38983 浏览
提问于 2025-04-17 12:10

根据我的理解,reduce函数会接收一个列表l和一个函数f。然后,它会先把这个函数f应用到列表的前两个元素上,接着再把函数f和下一个列表元素以及之前的结果一起反复调用。

所以,我定义了以下的函数:

下面这个函数用来计算阶乘。

def fact(n):
    if n == 0 or n == 1:
        return 1
    return fact(n-1) * n


def reduce_func(x,y):
    return fact(x) * fact(y)

lst = [1, 3, 1]
print reduce(reduce_func, lst)

现在,这个计算应该给我((1! * 3!) * 1!) = 6吧?可是,它却给了我720。为什么是720呢?看起来它还计算了6的阶乘。但我需要弄明白这是为什么。

有没有人能解释一下为什么会这样,还有解决办法?

我其实是想计算列表中所有元素的阶乘的乘积。我的备选方案是用循环来计算。但我更想用reduce。

9 个回答

33

理解 reduce() 最简单的方法就是看看它在纯 Python 中的对应代码:

def myreduce(func, iterable, start=None):
    it = iter(iterable)
    if start is None:
        try:
            start = next(it)
        except StopIteration:
            raise TypeError('reduce() of empty sequence with no initial value')
    accum_value = start
    for x in it:
        accum_value = func(accum_value, x)
    return accum_value

你会发现,只有把阶乘函数应用到最右边的参数上,才是有意义的:

def fact(n):
    if n == 0 or n == 1:
        return 1
    return fact(n-1) * n

def reduce_func(x,y):
    return x * fact(y)

经过这个小修改,代码就能像你预期的那样输出 6 了 :-)

>>> lst = [1, 3, 1]
>>> myreduce(reduce_func, lst)
6
79

其他的回答都很棒。我这里简单加一个我觉得很容易理解的例子,来说明一下 reduce() 是怎么工作的:

>>> reduce(lambda x,y: x+y, [47,11,42,13])
113

这个计算过程如下:

在这里输入图片描述

(来源) (镜像)

1

好的,明白了:

我需要先把数字和它们的阶乘对应起来,然后再用乘法操作符来调用reduce函数。

所以,这样做是可以的:

lst_fact = map(fact, lst)
reduce(operator.mul, lst_fact)

撰写回答