我试图在循环中创建lambdas迭代一个对象列表:
lambdas_list = []
for obj in obj_list:
lambdas_list.append(lambda : obj.some_var)
Run Code Online (Sandbox Code Playgroud)
现在,如果我遍历lambdas列表并像这样调用它们:
for f in lambdas_list:
print f()
Run Code Online (Sandbox Code Playgroud)
我得到了相同的价值.这是最后的价值obj在obj_list,因为那是在列表迭代器的块中的最后一个变量.任何想法都能很好地(pythonic)重写代码以使其工作?
Vau*_*ato 30
请改用此行:
lambdas_list.append(lambda obj=obj: obj.some_var)
Run Code Online (Sandbox Code Playgroud)
die*_*dha 13
您必须使用默认分配捕获变量
Run Code Online (Sandbox Code Playgroud)lambdas_list = [ lambda i=o: i.some_var for o in obj_list ]
或者,使用闭包来捕获变量
Run Code Online (Sandbox Code Playgroud)lambdas_list = [ (lambda a: lambda: a.some_var)(o) for o in obj_list ]
在这两种情况下,关键是确保将obj_list列表中的每个值分配给唯一范围.
您的解决方案不起作用,因为词法变量obj是从父作用域(the for)引用的.
默认分配有效,因为我们i从lambda范围引用.我们使用默认赋值通过使变量成为lambda定义的一部分并因此使其范围成为隐式"传递"变量.
闭包解决方案的工作原理是因为变量"传递"是显式的,lambda直接执行到外部,因此在列表理解期间创建绑定并返回lambda引用该绑定的内部.因此,当内部lambda实际执行时,它将引用在外部lambda范围中创建的绑定.
您可以执行以下操作:
def build_lambda(obj):
return lambda : obj.some_var
lambdas_list = []
for obj in obj_list:
lambdas_list.append(build_lambda(obj))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11329 次 |
| 最近记录: |