2011-09-25 60 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范围内创建的绑定。