2011-09-25 61 views
20

thể trùng lặp:
What do (lambda) function closures capture in Python?
lambda function don't closure the parameter in Python?Tạo lambda bên trong một vòng lặp

tôi đang cố gắng để tạo ra lambdas bên trong một vòng lặp đó lặp trên một danh sách các đối tượng:

lambdas_list = [] 
for obj in obj_list: 
    lambdas_list.append(lambda : obj.some_var) 

Bây giờ, nếu tôi lặp lại qua lambdas và gọi cho họ như sau:

for f in lambdas_list: 
    print f() 

Tôi nhận được cùng một giá trị. Đó là giá trị của số obj cuối cùng trong obj_list vì đó là biến cuối cùng trong khối của trình vòng lặp danh sách. Bất kỳ ý tưởng fn một tốt (pythonic) viết lại của mã để làm cho nó hoạt động?

+1

xem http://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python/2295372#2295372 và http://stackoverflow.com/questions/7514093/lambda -function-dont-closure-the-parameter-in-python. –

+0

câu trả lời mô tả nhất: http://stackoverflow.com/questions/938429/scope-of-python-lambda-functions-and-their-parameters/938493#938493 –

Trả lời

22

Sử dụng dòng này thay vì:

lambdas_list.append(lambda obj=obj: obj.some_var) 
+0

Thanh lịch hơn sử dụng một phần. – zoujyjs

4

Bạn có thể làm một cái gì đó như thế:

def build_lambda(obj): 
    return lambda : obj.some_var 

lambdas_list = [] 
for obj in obj_list: 
    lambdas_list.append(build_lambda(obj)) 
8

Bạn có thể phải nắm bắt những biến sử dụng bài tập mặc định

lambdas_list = [ lambda i=o: i.some_var for o in obj_list ] 

o r, đóng cửa sử dụng để nắm bắt những biến

lambdas_list = [ (lambda a: lambda: a.some_var)(o) for o in obj_list ] 

Trong cả hai trường hợp, quan trọng là để đảm bảo mỗi giá trị trong danh sách obj_list được gán cho một phạm vi độc đáo.

Giải pháp của bạn không hoạt động vì biến từ vựng obj được tham chiếu từ phạm vi gốc (số for).

Bài tập mặc định hoạt động vì chúng tôi tham chiếu i từ phạm vi lambda. Chúng tôi sử dụng nhiệm vụ mặc định để làm cho "chuyển" biến tiềm ẩn bằng cách biến nó trở thành một phần của định nghĩa lambda và do đó phạm vi của nó.

Giải pháp đóng cửa hoạt động vì biến "chuyển" rõ ràng, vào bên ngoài lambda được thực hiện ngay lập tức, do đó tạo liên kết trong quá trình hiểu danh sách và trả về bên trong lambda. Vì vậy, khi bên trong lambda thực sự thực hiện nó sẽ được tham chiếu các ràng buộc được tạo ra trong phạm vi lambda bên ngoài.

Các vấn đề liên quan