首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lambda函数如何引用python中的参数?

lambda函数如何引用python中的参数?
EN

Stack Overflow用户
提问于 2011-03-04 05:44:13
回答 4查看 1.1K关注 0票数 6

我是Python的新手。我的任务很简单--我需要一个函数列表,我可以用它来批量处理事情。所以我用了一些例子

代码语言:javascript
复制
fs = [lambda x: x + i for i in xrange(10)]

令人惊讶的是,

代码语言:javascript
复制
[f(0) for f in fs]

给了我像[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]一样的结果。这不是我所期望的,因为我希望变量i在不同的函数中有不同的值。

所以我的问题是:

  1. 是lambda中的变量i,是全局的还是本地的?
  2. 有类似于javascript中的“闭包”的概念吗?我的意思是,这里的每个lambda都有对i变量的引用,还是只保存了每个变量中i值的一个副本?
  3. ,如果我希望输出在这个例子中是[0, 1, .....9]呢?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-03-04 05:48:25

它看起来有点混乱,但你可以通过这样的方式得到你想要的东西:

代码语言:javascript
复制
>>> fs = [(lambda y: lambda x: x + y)(i) for i in xrange(10)]
>>> [f(0) for f in fs]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

通常,Python支持类似于Javascript中的“闭包”概念。但是,对于列表理解中的lambda表达式的这种特殊情况,似乎i只绑定一次并接连接收每个值,让每个返回的函数都表现为i为9。上面的黑客使用捕获的y值,将i的每个值显式地传递给一个返回另一个lambda的lambda。

票数 10
EN

Stack Overflow用户

发布于 2011-03-04 06:55:04

您在这里遇到的问题是“早期绑定”和“后期绑定”之间的区别。

当Python从外部作用域(本例中是i)查找变量时,它使用后期绑定。这意味着它在调用函数时看到该变量的值,而不是在定义函数时看到该值。

因此,在您的示例代码中,所有10个lambda函数都看到通过循环过程( 9 )分配给9变量的最终值。

Greg的回答显示了一种强制早期绑定行为的方法(即创建一个额外的闭包并在循环中立即调用它)。

另一种常用的强制早期绑定语义的方法是“默认参数哈克”,它在函数定义时将变量绑定为默认参数:

代码语言:javascript
复制
>>> fs = [(lambda x, _i=i: x + _i) for i in xrange(10)]
>>> [f(0) for f in fs]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

这两种方法都有效。Greg的优点是不影响返回函数的签名,默认参数攻击比定义命名函数时添加额外的闭包级别要快得多,而不是使用lambda表达式。

票数 6
EN

Stack Overflow用户

发布于 2011-03-04 05:48:49

  1. 变量i是列表理解的本地变量,但是它对lambda是可用的,因为lambda在它的范围内。
  2. 是的,lambda是闭包。变量绑定可能并不总是以您希望的方式工作,但它们是闭包。不过,您不应该严重依赖它们。
  3. 您只想在xrange(10)上循环一下。您可以使用lambdas (见另一个答案)来完成这个任务,但是您不会想这样做。羔羊应该非常谨慎地使用。--

lambda这样做的原因是因为对于每个循环,i都是反弹的。因为我不是lambda的本地用户,所以它也会发生变化,它持有的最后一个值是9,所以您所做的就是0 + 9 10次。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5190146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档