gpt4 book ai didi

带有生成器的 Python 闭包

转载 作者:太空狗 更新时间:2023-10-30 02:15:37 24 4
gpt4 key购买 nike

def multipliers():
return [lambda x : i * x for i in range(4)]

print [m(2) for m in multipliers()]

我部分理解(这很危险)i 对所有函数都是相同的原因,因为 Python 的闭包是后期绑定(bind)的。

输出是 [6, 6, 6, 6](不是我预期的 [0, 2, 4, 6])。


我看到它在生成器上运行良好,我的预期输出低于版本。

def multipliers():
return (lambda x : i * x for i in range(4))

print [m(2) for m in multipliers()]

任何简单的解释为什么它在以下版本中工作?

最佳答案

之所以有效,是因为您在创建下一个函数之前调用了每个函数。生成器是惰性的,它立即生成每个函数,所以在 i 递增之前。比较是否在调用函数之前强制消耗所有生成器:

>>> def multipliers():
... return (lambda x : i * x for i in range(4))
...
>>> print [m(2) for m in multipliers()]
[0, 2, 4, 6]
>>> print [m(2) for m in list(multipliers())]
[6, 6, 6, 6]

如果你想要提前绑定(bind)那么你可以在这里用默认参数模拟它:

>>> def multipliers():
... return (lambda x, i=i : i * x for i in range(4))
...
>>> print [m(2) for m in multipliers()]
[0, 2, 4, 6]
>>> print [m(2) for m in list(multipliers())]
[0, 2, 4, 6]

澄清我对生成器惰性的评论:生成器 (lambda x : i * x for i in range(4)) 将遍历 i 的值从 0 到 3(含),但当 i 仍为 0 时它会产生第一个函数,此时它不会对 1 到 3 的情况做任何事情(这就是我们说它的原因很懒)。

列表理解 [m(2) for m in multipliers()] 立即调用第一个函数 m,所以 i 仍然是0。然后循环的下一次迭代检索另一个函数 m,其中 i 现在是 1。再次立即调用该函数,因此它看到 i如 1. 等等。

关于带有生成器的 Python 闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49301738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com