ash*_*shu 2 python lambda function higher-order-functions
在此代码片段中
def D(m, x):
print(m)
return x
print((lambda x: D(1, D(2, D(4, x))))(5))
print("\n\n\n")
print(D(1, lambda x: D(2, D(4, x)))(5))
Run Code Online (Sandbox Code Playgroud)
我们看到以下输出
4
2
1
5
1
4
2
5
Run Code Online (Sandbox Code Playgroud)
为什么输出顺序不同?看起来当 D 的参数是 lambda 时,它会在稍后计算,而如果它是一个函数,它会先计算?我怎么理解这一点?
所有参数均在函数实际调用时计算。
\n在第一个中print,我们有一个由 lambda 表达式定义的函数,应用于 5。
在第二个中print,我们D需要对它进行评估才能获得要应用的函数5。
什么是D?它基本上是一个恒等函数,在返回另一个值之前打印一个值作为副作用。让我们稍微重写一下:
def Dc(m):\n def identity(x):\n return x\n print(m)\n return identity\nRun Code Online (Sandbox Code Playgroud)\n花点时间说服自己这Dc(m)(x)相当于D(m, x)。
Dc现在让我们使用in 代替重写原始示例D。
print((lambda x: Dc(1)(Dc(2)(Dc(4)(x))))(5))\nprint(Dc(1)(lambda x: Dc(2)(Dc(4)(x)))(5))\nRun Code Online (Sandbox Code Playgroud)\n如果我们将 Python 假装成函数组合运算符,就会更容易看出。
\nf \xe2\x88\x98 g = lambda x: f(g(x))\nRun Code Online (Sandbox Code Playgroud)\n(f \xe2\x88\x98 g)(x)只需调用g(x),然后将结果传递给f.
重要提示:请记住, 的任何副作用g都会在 的副作用之前发生f。
现在让我们使用新的组合运算符重写我们的两个示例。
\nprint((Dc(1) \xe2\x88\x98 Dc(2) \xe2\x88\x98 Dc(4))(5)) # print(t(5)) where t = Dc(1) \xe2\x88\x98 Dc(2) \xe2\x88\x98 Dc(4) \nprint(Dc(1)((Dc(2) \xe2\x88\x98 Dc(4))(5)) # print(Dc(1)(t)(5)) where t = Dc(2) \xe2\x88\x98 Dc(4)\nRun Code Online (Sandbox Code Playgroud)\n由于组合本身不会产生副作用,并且函数组合具有结合性,因此我们可以分解出Dc(2) \xe2\x88\x98 Dc(4)使其更易于阅读。
t = Dc(2) \xe2\x88\x98 Dc(4)\nprint((Dc(1) \xe2\x88\x98 t)(5)\nprint(Dc(1)(t)(5))\nRun Code Online (Sandbox Code Playgroud)\n现在很容易看到发生了什么
\nDc(1)on t,在调用 之前立即输出 1 t(5),后者在返回 5 之前输出 4 和 2。