列表推导式 [lambda x,i*x for i in range(4)]解析
python中 [lambda x: i * x for i in range(4)] 是一个列表推导式,它创建了一个包含 4 个匿名函数(lambda 函数)的列表。这些函数的行为在迭代器和生成器中可能会表现出不同的结果,原因与 闭包 和 作用域 有关。
funcs = [lambda x: i * x for i in range(4)]
这段代码创建了一个列表 funcs,其中包含 4 个 lambda 函数。
每个 lambda 函数的形式是 lambda x: i * x。
变量 i 是来自 for i in range(4) 的循环变量。
这些 lambda 函数共享同一个变量 i,而 i 的值在循环结束后是 3(range(4) 的最后一个值)。
因此,无论调用哪个 lambda 函数,它们都会使用 i = 3 来计算结果。
funcs = [lambda x: i * x for i in range(4)]
print([f(2) for f in funcs]) # 输出: [6, 6, 6, 6]
所有 lambda 函数都使用了 i = 3,因此 2 * 3 = 6。
如果使用迭代器(如列表推导式),i 的值会在循环结束后固定为 3,因此所有 lambda 函数都会使用 i = 3。
如果使用生成器表达式,i 的值会在每次生成 lambda 函数时捕获当前的值,因此每个 lambda 函数会使用不同的 i 值。
funcs = (lambda x: i * x for i in range(4))
print([f(2) for f in funcs]) # 输出: [0, 2, 4, 6]
生成器表达式是惰性求值的,每次生成一个 lambda 函数时,i 的值是当前的循环值。
因此,每个 lambda 函数捕获了不同的 i 值(0, 1, 2, 3)。
:在列表推导式中,所有 lambda 函数共享同一个变量 i,而 i 的值在循环结束后固定为 3。
:生成器表达式是惰性求值的,每次生成 lambda 函数时,i 的值是当前的循环值。
如果你希望每个 lambda 函数捕获不同的 i 值,可以使用以下方法:
通过将 i 作为 lambda 函数的默认参数,可以在定义时捕获当前的值。
funcs = [lambda x, i=i: i * x for i in range(4)]
print([f(2) for f in funcs]) # 输出: [0, 2, 4, 6]
i=i将当前的 i 值作为默认参数传递给 lambda 函数。
funcs = [create_function(i) for i in range(4)]
print([f(2) for f in funcs]) # 输出: [0, 2, 4, 6]
create_function是一个工厂函数,它为每个 i 创建一个新的 lambda 函数。
funcs = (lambda x, i=i: i * x for i in range(4))
print([f(2) for f in funcs]) # 输出: [0, 2, 4, 6]
问题原因:列表推导式中的 lambda 函数共享同一个变量 i,导致所有函数使用相同的 i 值。
生成器的行为:生成器表达式是惰性求值的,每次生成 lambda 函数时捕获当前的 i 值。
通过这些方法,可以确保每个 lambda 函数捕获不同的 i 值,从而得到正确的结果。

浙公网安备 33010602011771号