Sea*_*ney 1 python reduce lambda
我只是在学习 Python,不明白我从 reduce 函数中得到的行为。我看过很多例子,当你想乘法时,你可以使用 reduce 来执行与 sum 等效的函数:
f = [2,3,4]
reduce(lambda x,y: x*y,f)
Run Code Online (Sandbox Code Playgroud)
这给了我我期望的价值。但我需要乘以所有的倒数。我以为我可以这样做:
reduce(lambda x,y: 1/x * 1/y, f)
Run Code Online (Sandbox Code Playgroud)
但结果是 1.5 而不是一些小得多的十进制答案。我究竟做错了什么?
在x
每次调用是最后一次通话的结果(这是只对第一个调用的直接投入一个),这样1 / x
每次取前一个结果的倒数。要修复,您需要将 更改lambda
为仅乘以新数字的倒数,而不是累加值。您还需要提供一个初始中性值 ( 1
) 以便f
正确取倒数中的第一个值(否则,它将是f[0]
乘以 的倒数的纯值f[1:]
):
# x is accumulated product of reciprocals to date, *DON'T* take reciprocal again
reduce(lambda x, y: x * (1 / y), f, 1)
# ^ multiplicative identity is correct neutral value here
Run Code Online (Sandbox Code Playgroud)
也就是说,您可以稍微简化一些;x * (1 / y)
是(粗略地,考虑到浮点精度问题)相当于x / y
,因此您可以进一步简化为:
reduce(lambda x, y: x / y, f, 1)
Run Code Online (Sandbox Code Playgroud)
或使用该operator
模块来推动各项工作,以C层(如果只有重要的f
可能是非常大的):
import operator
reduce(operator.truediv, f, 1)
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,这都会得到预期的结果:
>>> (1/2) * (1/3) * (1/4)
0.041666666666666664
>>> reduce(lambda x,y: x * (1 / y), f, 1)
0.041666666666666664
>>> reduce(lambda x,y: x / y, f, 1)
0.041666666666666664
>>> reduce(operator.truediv, f, 1)
0.041666666666666664
Run Code Online (Sandbox Code Playgroud)
正如下面的评论中所指出的,计算单个倒数并将它们全部相乘int
比仅计算 中所有值的乘积更慢且更容易出错(尤其是当所有输入为 时)f
,然后计算该乘积的倒数一次,在最后。在 Python 3.8+ 上,使用math.prod
,这很简单:
>>> 1 / math.prod(f)
0.041666666666666664
Run Code Online (Sandbox Code Playgroud)
在旧版本的 Python 上,您必须创建自己的产品计算函数,但使用reduce
+很容易做到operator.mul
:
>>> 1 / reduce(operator.mul, f)
0.041666666666666664
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
468 次 |
最近记录: |