为了账号安全,请及时绑定邮箱和手机立即绑定

在循环内创建lambda

在循环内创建lambda

神不在的星期二 2019-07-27 11:12:57
在循环内创建lambda 我试图在循环中创建lambdas迭代一个对象列表:lambdas_list = []for obj in obj_list:    lambdas_list.append(lambda : obj.some_var)现在,如果我遍历lambdas列表并像这样调用它们:for f in lambdas_list:     print f()我得到了相同的价值。这是最后的价值obj在obj_list,因为那是在列表迭代器的块中的最后一个变量。任何想法都能很好地(pythonic)重写代码以使其工作?
查看完整描述

3 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

请改用此行:

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


查看完整回答
反对 回复 2019-07-27
?
MM们

TA贡献1886条经验 获得超2个赞

您必须使用默认分配捕获变量

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

或者,使用闭包来捕获变量

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

在这两种情况下,关键是确保将obj_list列表中的每个值分配给唯一范围。

您的解决方案不起作用,因为词法变量obj是从父作用域(the for)引用的。

默认分配有效,因为我们ilambda范围引用。我们使用默认赋值通过使变量成为lambda定义的一部分并因此使其范围成为隐式“传递”变量。

闭包解决方案的工作原理是因为变量“传递”是显式的,lambda直接执行到外部,因此在列表理解期间创建绑定并返回lambda引用该绑定的内部。因此,当内部lambda实际执行时,它将引用在外部lambda范围中创建的绑定。


查看完整回答
反对 回复 2019-07-27
?
森栏

TA贡献1810条经验 获得超5个赞

你可以这样做:

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

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


查看完整回答
反对 回复 2019-07-27
  • 3 回答
  • 0 关注
  • 422 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信