python - lambda 函数的列表或生成器在 Python 中不会返回相同的结果

标签 python python-3.x functional-programming

当我这样做时:

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

谁能解释一下为什么吗?

最佳答案

您的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()) 操作,您会看到同样的结果,强制生成器像列表理解一样一直走到末尾。

关于python - lambda 函数的列表或生成器在 Python 中不会返回相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37283846/

相关文章:

python - 使用 python 的 xlrd、xlwt 和 xlutils.copy 保留样式

python-3.x - Pandas 数据帧 : create a matrix-like with 0 and 1

python - 在 Python 3.5 中,如何将函数指定为类型提示?

scala - 功能流水线scala

haskell - 在标准 ML 中根据 foldr 定义 foldl

java - 按流排序不适用

python - 用 python regexp 只替换一个字符的单个实例

python numpy 数组按键搜索

python - 单个函数的 Numpy 均值和方差?

python - 一个 Python 项目可以同时使用 2.x 和 3.x 代码吗?