lambda functs的列表或生成器在Python中不返回相同的结果

2024-04-26 01:00:24 发布

您现在位置:Python中文网/ 问答频道 /正文

当我这样做时:

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: lambdainforreturndefcreaterangeprint
2条回答

正如BrenBarn提到的,列表理解中的变量i是理解范围的局部变量。如果使用括号,这将起作用:

def create_funcs():
    return (lambda: i for i in range(5))

for f in create_funcs():
    print(f())

0
1
2
3
4

您的lambda函数从周围的作用域捕获变量i。如this question所述,这个范围就是理解的范围。你知道吗

循环一次遍历一个生成器中的项,并在推进生成器之前调用每个项。当您获得第一个函数时,生成器将在i为0的状态下挂起,因此这是函数看到的值。当您推进生成器时,它将i设置为1,然后您将得到一个获取该值的函数。生成器“等待”更改i,直到您进入下一个函数。你知道吗

在列表理解中,您可以一次获得所有函数。但是所有人仍然在理解范围内引用相同的变量i。因为列表理解一直到最后,所以在您有机会使用任何函数之前,i一直到4。你知道吗

在这两种情况下,lambda都引用了理解范围中的变量。只是在生成器理解中,这个变量在您调用了前面的函数之后才会前进。如果存储第一个函数,则可以看到与列表理解情况类似的行为,但在再次推进生成器之前不要调用它:

def create_funcs():
    return (lambda: i for i in range(5))

gen = create_funcs()
f1 = next(gen)
f2 = next(gen)
print(f1())
print(f2())

输出为

1
1

因为我改进了生成器,i是1,所以f1f2在调用它们时都可以看到这个值。如果执行for f in list(create_funcs()),则可以看到相同的情况,强制生成器像列表理解一样一直执行到底。你知道吗

相关问题 更多 >