2012-06-18 18 views
7

W pętli, próbuję odroczyć porównanie dwóch wartości() s dwóch węzłów do późniejszego czasu.Odroczona ocena z lambda w Pythonie

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 

Wszystkie wyniki są prawdziwe (ponieważ i, j == 2,5 dla wszystkich lambdas). Jak mogę odłożyć wykonanie lambda, dopóki nie zostanie wywołane, ale z poprawnymi powiązaniami zmiennych? A wyrażenia w lambda niekoniecznie oznaczają równość ... jest wiele innych, bardziej zaangażowanych wyrażeń.

Dzięki za pomoc!

+0

Nie jestem do końca pewien, co próbujesz zrobić. Wyrażenie lambda wydaje mi się tu niepotrzebne. Dlaczego nie możesz po prostu wykonać polecenia 'results.append (węzły [i] .value() == węzły [j] .value())'? – JAB

Odpowiedz

11

Aby powiązać bieżące wartości i i j z funkcją, zamiast szukać jej w zewnętrznym zasięgu, można użyć wartości zamknięcia lub domyślnego argumentu. Najprostszym sposobem, aby to zrobić jest użycie domyślnych wartości argumentów w swojej lambda:

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

Oto jak to będzie wyglądać jako zamknięcie:

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

idiomatyczne sposobem jest użycie domyślnej argumentu:

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

Zmień to:

[f() for f in [lambda i=i: i for i in range(3)]] 
[0, 1, 2] 
5

owinąć go w innym lambda:

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

lub w ładniejszy sposób z partial:

from functools import partial 

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

domyślne argumenty Sztuką jest, dobrze ... podstęp, i sugeruję, aby uniknąć to.

+1

+1 za sugerowanie częściowego. – jdi