2012-06-18 95 views
7

在一個循環中,我試圖推遲比較兩個節點的兩個值()到以後的時間。在Python中使用lambda推遲評估

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 

結果都是真的(因爲i,j == 2,5爲所有的lambda)。我如何推遲lambda的執行直到它被實際調用,但是使用正確的變量綁定? lambda中的表達式並不一定都是相等的......還有一些其他更多涉及的表達式。

感謝您的幫助!

+0

我不確定你想要做什麼。這裏的lambda表達式對我來說似乎沒有必要。爲什麼不能只執行'results.append(nodes [i] .value()== nodes [j] .value())'? – JAB

回答

11

要將當前值ij綁定到函數而不是在外部作用域中查找,可以使用閉包或默認參數值。要做到這一點最簡單的方法是在你的拉姆達使用默認參數值:

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)) 
3

慣用的方法是使用默認參數:

[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] 
5

敷在另一個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)) 

默認參數訣竅就是,嗯......一招,我會建議避免它。

+1

+1表示偏好。 – jdi