2011-09-25 104 views
20

可能重複:
What do (lambda) function closures capture in Python?
lambda function don't closure the parameter in Python?創建拉姆達一個循環內

我試圖在循環中創建lambda表達式,超過對象的列表迭代:

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

現在,如果我遍歷lambda表達式列表並且像這樣調用它們:

for f in lambdas_list: 
    print f() 

我得到相同的值。這是obj_list中最後一個obj的值,因爲這是列表迭代器塊中的最後一個變量。對代碼進行一次很好的(pythonic)重寫以使其工作的任何想法?

+1

請參閱http://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python/2295372#2295372和http://stackoverflow.com/questions/7514093/lambda - 功能 - 不要閉合-的參數功能於蟒蛇。 –

+0

最具描述性的答案:http://stackoverflow.com/questions/938429/scope-of-python-lambda-functions-and-their-parameters/938493#938493 –

回答

22

使用此行:

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

比使用部分更優雅。 – zoujyjs

4

你可以做這樣的事情:

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

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

你要麼選擇使用默認分配

lambdas_list = [ lambda i=o: i.some_var for o in obj_list ] 
捕捉變量

o R,使用閉捕捉變量

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

在這兩種情況下,關鍵是要確保在OBJ_LIST列表中的每個值被分配到一個獨特的範圍。因爲詞法變量obj從父作用域(for)引用

您的解決方案沒有奏效。

由於我們參考lambda範圍內的i,默認分配工作。我們使用默認分配來使得隱含的變量「​​通過」,使其成爲lambda定義的一部分,並因此成爲其範圍。

由於變量「passing」是明確的,所以閉包解決方案工作到立即執行的外部lambda,從而在列表理解期間創建綁定並返回引用該綁定的內部lambda。所以當內部lambda實際執行時,它將引用在外部lambda範圍內創建的綁定。