循环中的Python Lambda

循环中的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 ?}

我真的不明白为什么。你有什么建议吗?


呼唤远方
浏览 1603回答 5
5回答

HUH函数

您需要为创建的每个函数绑定d。这样做的一种方法是将其作为具有默认值的参数传递:lambda&nbsp;d=d:&nbsp;self.root.change_directory(d)现在,函数中的d使用该参数,尽管它具有相同的名称,并且在创建函数时将计算该参数的默认值。为了帮助你了解这个:lambda&nbsp;bound_d=d:&nbsp;self.root.change_directory(bound_d)记住默认值是如何工作的,例如对于列表和DECTS这样的可变对象,因为您正在绑定一个对象。这种带有默认值的参数的习语很常见,但如果您内省函数参数并根据它们的存在来确定该做什么,则可能会失败。您可以使用另一个闭包来避免参数:(lambda&nbsp;d=d:&nbsp;lambda:&nbsp;self.root.change_directory(d))()#&nbsp;or(lambda&nbsp;d:&nbsp;lambda:&nbsp;self.root.change_directory(d))(d)

临摹微笑

这是由于d被约束的点。lambda函数都指向变量&nbsp;d而不是现在价值所以当你更新d在下一次迭代中,在所有函数中都会看到此更新。更简单的例子是:funcs&nbsp;=&nbsp;[]for&nbsp;x&nbsp;in&nbsp;[1,2,3]: &nbsp;&nbsp;funcs.append(lambda:&nbsp;x)for&nbsp;f&nbsp;in&nbsp;funcs: &nbsp;&nbsp;print&nbsp;f()#&nbsp;output:333您可以通过添加一个额外的函数来解决这个问题,如下所示:def&nbsp;makeFunc(x): &nbsp;&nbsp;return&nbsp;lambda:&nbsp;x funcs&nbsp;=&nbsp;[]for&nbsp;x&nbsp;in&nbsp;[1,2,3]: &nbsp;&nbsp;funcs.append(makeFunc(x))for&nbsp;f&nbsp;in&nbsp;funcs: &nbsp;&nbsp;print&nbsp;f()#&nbsp;output:123还可以修复lambda表达式中的作用域。lambda&nbsp;bound_x=x:&nbsp;bound_x但是总的来说,这是不良好的实践,因为你已经改变了你的功能的签名。

子衿沉夜

我也遇到了同样的问题。所选的解决方案对我有很大帮助,但我认为有必要添加一个精度,以使问题的代码变得实用:在循环之外定义lambda函数。顺便说一下,默认值是不必要的。foo&nbsp;=&nbsp;lambda&nbsp;d:&nbsp;lambda&nbsp;:&nbsp;self.root.change_directory(d)for&nbsp;d&nbsp;in&nbsp;directorys: &nbsp;&nbsp;&nbsp;&nbsp;self.command["cd&nbsp;"&nbsp;+&nbsp;d]&nbsp;=&nbsp;(foo(d))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python