2012-06-18 26 views
7

Trong một vòng lặp, tôi đang cố trì hoãn việc so sánh hai giá trị() s của hai Nút với một thời gian sau đó.Đánh giá trì hoãn với lambda trong Python

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 

Kết quả đều đúng (vì i, j == 2,5 cho tất cả các lambdas). Làm thế nào tôi có thể trì hoãn việc thực hiện lambda cho đến khi nó thực sự được gọi, nhưng với các ràng buộc biến đúng? Và các biểu thức trong lambda không nhất thiết là bình đẳng ... có một loạt các biểu thức khác liên quan nhiều hơn.

Cảm ơn bạn đã trợ giúp!

+0

Tôi không thực sự chắc chắn những gì bạn đang cố gắng làm. Biểu thức lambda dường như không cần thiết đối với tôi ở đây. Tại sao bạn không thể làm 'results.append (nodes [i] .value() == nodes [j] .value())'? – JAB

Trả lời

11

Để liên kết các giá trị hiện tại của ij với hàm thay vì để nó nhìn vào phạm vi bên ngoài, bạn có thể sử dụng giá trị đối số mặc định hoặc đóng. Cách đơn giản nhất để làm điều này là sử dụng các giá trị tham số mặc định trong lambda của bạn:

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

Sau đây là cách nó sẽ trông như một đóng cửa:

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

Cách thành ngữ là sử dụng một đối số mặc định:

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

Thay đổi này để:

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

Wrap nó trong lambda khác:

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

hoặc theo một cách đẹp hơn, với partial:

from functools import partial 

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

Mặc định lập luận Bí quyết là, cũng ... một thủ thuật, và tôi muốn đề nghị để tránh nó.

+1

+1 để đề xuất một phần. – jdi