首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python用lambda函数封装作用域变量

Python用lambda函数封装作用域变量
EN

Stack Overflow用户
提问于 2016-12-06 14:02:43
回答 2查看 1.2K关注 0票数 5

我写了这个简单的代码:

代码语言:javascript
复制
def makelist():
  L = []
  for i in range(5):
    L.append(lambda x: i**x)
  return L

好吧,现在我打电话

代码语言:javascript
复制
mylist = makelist()

因为在以后调用嵌套函数时会查找封闭作用域变量,因此它们实际上都记住了相同的值:正因为如此,我希望找到循环变量在上次循环迭代中的值,但是当我检查我的列表时,我看到:

代码语言:javascript
复制
>>> mylist[0](0)
1
>>> mylist[0](1)
4
>>> mylist[0](2)
16
>>> 

我很困惑,为什么我的代码不保留最后一个循环值?为什么我不必显式地用默认参数保留作用域值,比如:

代码语言:javascript
复制
L.append(lambda x, i=i: i ** x)

提前感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-06 14:11:07

尽管随着时间的推移,i接受多个值,但实际上只有一个变量i。在循环期间,i的内容正在更改。但是闭包捕获的是变量,而不是值。在lambda内部,在调用它之前,不会对其进行任何评估。在调用函数时,访问i的当前值,这恰好是最后一个值。

至于为什么i=i解决了这个问题,例如在http://docs.python-guide.org/en/latest/writing/gotchas/#what-does-happen (公共Gotchas)中解释了这个问题:

在定义函数时,Python的默认参数只计算一次,而不是每次调用函数时(比如Ruby)。这意味着,如果您使用一个可变的默认参数并对其进行变异,那么您将在以后对该函数的所有调用中对该对象进行变异。

因此,在创建闭包时,每个发生在闭包内的新绑定(恰巧被命名为i,就像外部的那样)都有其默认值。因此,您的"right“值已经就位,可以在调用闭包时使用。

票数 5
EN

Stack Overflow用户

发布于 2018-04-28 10:48:41

我会尽我最大的努力用更简单的术语把它分解一下。

1 -

for循环正在循环,并在列表中追加‘un调用’lambda函数。--就你的例子而言,它会这样做5次。

2

现在.。在for循环完成后,循环中"i“的iterations..the值将为"4”。- lambda函数不包含"i“的任何值,因为您还没有调用它。

3

当您调用lambda函数时,只有才会在循环完成它的迭代时‘记住’变量"i“的值,即"4”。

4

然后Lambda插入"4“作为参数来进行计算。

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

https://stackoverflow.com/questions/40997189

复制
相关文章

相似问题

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