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

循环中的Python Lambda

循环中的Python Lambda

呼唤远方 2019-06-13 14:53:36
循环中的Python Lambda考虑到以下代码片段:# directorys == {'login': <object at ...>, 'home': <object at ...>}for d in directorys:     self.command["cd " + d] = (lambda : self.root.change_directory(d))我希望创建一个包含两个功能的字典,如下所示:# Expected :self.command == {     "cd login": lambda: self.root.change_directory("login"),     "cd home": lambda: self.root.change_directory("home")}但是看起来,生成的两个lambda函数完全相同:# Result :self.command == {     "cd login": lambda: self.root.change_directory("login"),     "cd home": lambda: self.root.change_directory("login")   # <- Why login ?}我真的不明白为什么。你有什么建议吗?
查看完整描述

5 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

您需要为创建的每个函数绑定d。这样做的一种方法是将其作为具有默认值的参数传递:

lambda d=d: self.root.change_directory(d)

现在,函数中的d使用该参数,尽管它具有相同的名称,并且在创建函数时将计算该参数的默认值。为了帮助你了解这个:

lambda bound_d=d: self.root.change_directory(bound_d)

记住默认值是如何工作的,例如对于列表和DECTS这样的可变对象,因为您正在绑定一个对象。

这种带有默认值的参数的习语很常见,但如果您内省函数参数并根据它们的存在来确定该做什么,则可能会失败。您可以使用另一个闭包来避免参数:

(lambda d=d: lambda: self.root.change_directory(d))()# or(lambda d: lambda: self.root.change_directory(d))(d)


查看完整回答
反对 回复 2019-06-13
?
临摹微笑

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

这是由于d被约束的点。lambda函数都指向变量 d而不是现在价值所以当你更新d在下一次迭代中,在所有函数中都会看到此更新。

更简单的例子是:

funcs = []for x in [1,2,3]:
  funcs.append(lambda: x)for f in funcs:
  print f()# output:333

您可以通过添加一个额外的函数来解决这个问题,如下所示:

def makeFunc(x):
  return lambda: x

funcs = []for x in [1,2,3]:
  funcs.append(makeFunc(x))for f in funcs:
  print f()# output:123

还可以修复lambda表达式中的作用域。

lambda bound_x=x: bound_x

但是总的来说,这是良好的实践,因为你已经改变了你的功能的签名。


查看完整回答
反对 回复 2019-06-13
?
子衿沉夜

TA贡献1828条经验 获得超3个赞

我也遇到了同样的问题。所选的解决方案对我有很大帮助,但我认为有必要添加一个精度,以使问题的代码变得实用:在循环之外定义lambda函数。顺便说一下,默认值是不必要的。

foo = lambda d: lambda : self.root.change_directory(d)for d in directorys:
    self.command["cd " + d] = (foo(d))


查看完整回答
反对 回复 2019-06-13
  • 5 回答
  • 0 关注
  • 1602 浏览
慕课专栏
更多

添加回答

举报

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