[英]Trying to solve with python map function with lambda expression inside for loop
[英]Generating functions inside loop with lambda expression in python
如果我列出两个函数列表:
def makeFun(i):
return lambda: i
a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
为什么列表a
和b
不以保存方式运行?
例如:
>>> a[2]()
2
>>> b[2]()
9
正如其他人所说,范围界定是问题所在。 请注意,您可以通过向 lambda 表达式添加额外参数并为其分配默认值来解决此问题:
>> def makeFun(i): return lambda: i
...
>>> a = [makeFun(i) for i in range(10)]
>>> b = [lambda: i for i in range(10)]
>>> c = [lambda i=i: i for i in range(10)] # <-- Observe the use of i=i
>>> a[2](), b[2](), c[2]()
(2, 9, 2)
结果是i
现在被明确地放置在仅限于lambda
表达式的范围内。
从技术上讲,lambda 表达式在全局作用域中可见的i
上是封闭的,最后设置为 9。这与在所有 10 个 lambda 中引用的i
相同。 例如,
i = 13
print b[3]()
在makeFun
函数中,lambda 在调用函数时定义的i
上关闭。 那是十个不同的i
。
一组函数 (a) 对传递的参数进行操作,另一组 (b) 对全局变量进行操作,然后将其设置为 9。检查反汇编:
>>> import dis
>>> dis.dis(a[2])
1 0 LOAD_DEREF 0 (i)
3 RETURN_VALUE
>>> dis.dis(b[2])
1 0 LOAD_GLOBAL 0 (i)
3 RETURN_VALUE
>>>
增加一些清晰度(至少在我看来)
def makeFun(i): return lambda: i
a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
a 使用 makeFun(i),它是一个带参数的函数。
b 使用 lambda: i 这是一个没有参数的函数。 它使用的 i 与之前的非常不同
为了使 a 和 b 相等,我们可以使两个函数不使用参数:
def makeFun(): return lambda: i
a = [makeFun() for i in range(10)]
b = [lambda: i for i in range(10)]
现在这两个函数都使用全局 i
>>> a[2]()
9
>>> b[2]()
9
>>> i=13
>>> a[2]()
13
>>> b[2]()
13
或者(更有用)让两者都使用一个参数:
def makeFun(x): return lambda: x
a = [makeFun(i) for i in range(10)]
b = [lambda x=i: x for i in range(10)]
我故意将 i 更改为 x ,其中变量是本地的。 现在:
>>> a[2]()
2
>>> b[2]()
2
成功 !
python中的Lambdas共享它们创建的变量范围。在你的第一种情况下,lambda的范围是makeFun的。 在第二种情况下,它是全局i
,它是 9 ,因为它是循环的剩余部分。
反正我是这么理解的。。。
不错的收获。 列表推导式中的 lambda 每次都看到相同的本地i
。
您可以将其重写为:
a = []
for i in range(10):
a.append(makefun(i))
b = []
for i in range(10):
b.append(lambda: i)
结果相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.