当我这样做时:
def create_funcs():
return (lambda: i for i in range(5))
for f in create_funcs():
print(f())
我得到了预期的结果:
1
2
3
4
但当我这么做的时候:
def create_funcs():
return [lambda: i for i in range(5)]
for f in create_funcs():
print(f())
我有个奇怪的想法:
4
4
4
4
有人能解释为什么吗?你知道吗
Tags:
正如BrenBarn提到的,列表理解中的变量
i
是理解范围的局部变量。如果使用括号,这将起作用:您的
lambda
函数从周围的作用域捕获变量i
。如this question所述,这个范围就是理解的范围。你知道吗循环一次遍历一个生成器中的项,并在推进生成器之前调用每个项。当您获得第一个函数时,生成器将在
i
为0的状态下挂起,因此这是函数看到的值。当您推进生成器时,它将i
设置为1,然后您将得到一个获取该值的函数。生成器“等待”更改i
,直到您进入下一个函数。你知道吗在列表理解中,您可以一次获得所有函数。但是所有人仍然在理解范围内引用相同的变量
i
。因为列表理解一直到最后,所以在您有机会使用任何函数之前,i
一直到4。你知道吗在这两种情况下,lambda都引用了理解范围中的变量。只是在生成器理解中,这个变量在您调用了前面的函数之后才会前进。如果存储第一个函数,则可以看到与列表理解情况类似的行为,但在再次推进生成器之前不要调用它:
输出为
因为我改进了生成器,
i
是1,所以f1
和f2
在调用它们时都可以看到这个值。如果执行for f in list(create_funcs())
,则可以看到相同的情况,强制生成器像列表理解一样一直执行到底。你知道吗相关问题 更多 >
编程相关推荐