12

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

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

结果都是 True (因为 i,j==2,5 对于所有 lambdas)。如何推迟 lambda 的执行,直到它被实际调用,但使用正确的变量绑定?并且 lambda 中的表达式不一定都是相等的……还有很多其他更复杂的表达式。

谢谢你的帮助!

4

3 回答 3

17

要将当前值i和函数绑定j到函数而不是让它在外部作用域中查找,您可以使用闭包或默认参数值。最简单的方法是在 lambda 中使用默认参数值:

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

这是一个闭包的样子:

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))
于 2012-06-18T16:31:36.083 回答
9

将其包装在另一个 lambda 中:

results.append((lambda x, y: lambda: nodes[x].value() == nodes[y].value()) (i, j))

或者以更好的方式,使用partial

from functools import partial

results.append(partial(lambda x, y: nodes[x].value() == nodes[y].value(), i, j))

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

于 2012-06-18T16:42:26.063 回答
4

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

[f() for f in [lambda: i for i in range(3)]]
[2, 2, 2]

将其更改为:

[f() for f in [lambda i=i: i for i in range(3)]]
[0, 1, 2]
于 2012-06-18T16:38:06.377 回答