使用Python中的lambda进行延迟评估

Alb*_*eit 9 python lambda deferred-execution

在循环中,我试图将两个节点的两个value()s的比较推迟到以后的时间.

class Node():
    def __init__(self, v):
        self.v = v
    def value(self):
        return self.v

nodes = [Node(0), Node(1), Node(2), Node(3), Node(4), Node(2)]
results = []
for i in [0, 1, 2]:
    j = i + 3
    results.append(lambda: nodes[i].value() == nodes[j].value())

for result in results:
    print result
Run Code Online (Sandbox Code Playgroud)

结果都是True(因为我,j == 2,5对于所有lambda).我怎样才能推迟执行lambda直到实际调用它,但是使用正确的变量绑定?lambda中的表达式并不一定都是相等的...还有一堆其他更复杂的表达式.

谢谢你的帮助!

And*_*ark 14

要绑定的当前值ij该函数,而不是让它看起来外的范围,你可以使用一个关闭或默认参数值.最简单的方法是在lambda中使用默认参数值:

for i in [0, 1, 2]:
    j = i + 3
    results.append(lambda i=i, j=j: nodes[i].value() == nodes[j].value())
Run Code Online (Sandbox Code Playgroud)

以下是封闭的外观:

def make_comp_func(i, j):
    return lambda: nodes[i].value() == nodes[j].value()

for i in [0, 1, 2]:
    j = i + 3
    results.append(make_comp_func(i, j))
Run Code Online (Sandbox Code Playgroud)


geo*_*org 8

把它换成另一个lambda:

results.append((lambda x, y: lambda: nodes[x].value() == nodes[y].value()) (i, j))
Run Code Online (Sandbox Code Playgroud)

或以更好的方式,用partial:

from functools import partial

results.append(partial(lambda x, y: nodes[x].value() == nodes[y].value(), i, j))
Run Code Online (Sandbox Code Playgroud)

默认参数技巧是,嗯...一个技巧,我建议避免它.


eca*_*mur 5

惯用的方法是使用默认参数:

[f() for f in [lambda: i for i in range(3)]]
[2, 2, 2]
Run Code Online (Sandbox Code Playgroud)

将其更改为:

[f() for f in [lambda i=i: i for i in range(3)]]
[0, 1, 2]
Run Code Online (Sandbox Code Playgroud)