减少功能如何工作?

Div*_*vya 40 python reduce

据我所知,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)
Run Code Online (Sandbox Code Playgroud)

现在,这不应该给我((1! * 3!) * 1!) = 6吗?但是,相反它给出了720.为什么720?它似乎也是一个因素6.但是,我需要理解为什么.

有人能解释为什么会发生这种情况并解决问题吗?

我基本上想要计算列表中所有条目的阶乘的乘积.备份计划是运行循环并计算它.但是,我更喜欢使用reduce.

Fra*_*urt 68

其他答案很棒.我只想添加一个我觉得很好理解的插图示例reduce():

>>> reduce(lambda x,y: x+y, [47,11,42,13])
113
Run Code Online (Sandbox Code Playgroud)

计算方法如下:

在此输入图像描述

(来源)(镜子)


Ray*_*ger 30

理解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 iterable:
        accum_value = func(accum_value, x)
    return accum_value
Run Code Online (Sandbox Code Playgroud)

你可以看到,只有你的reduce_func()才能将factorial应用于最右边的参数:

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)

lst = [1, 3, 1]
print reduce(reduce_func, lst)
Run Code Online (Sandbox Code Playgroud)

通过这个小修订,代码产生6你所期望的:-)

  • for循环应该迭代`it`,而不是`iterable`:`for x in it:` (3认同)

Ign*_*ams 10

你的函数调用fact()两个参数.你正在计算((1! * 3!)! * 1!).解决方法是仅在第二个参数上调用它,并传递reduce()初始值1.


Bro*_*ses 9

Python reduce文档中,

reduce(function,sequence)返回通过在序列的前两个项上调用(binary)函数,然后在结果和下一个项上构造的单个值,依此类推.

所以,踩过去.它计算reduce_func前两个元素,reduce_func(1, 3) = 1! * 3! = 6.然后,它计算reduce_func结果和下一个项目:reduce_func(6, 1) = 6! * 1! = 720.

你错过了,当第一个reduce_func调用的结果作为输入传递给第二个时,它在乘法之前被阶乘.


Div*_*vya 1

好的,我知道了:

我需要首先将数字映射到它们的阶乘,然后使用乘法运算符调用reduce。

所以,这会起作用:

lst_fact = map(fact, lst)
reduce(operator.mul, lst_fact)
Run Code Online (Sandbox Code Playgroud)