为什么在循环中定义的带有不同值的Python lambda函数都会返回相同的结果
在理解为什么在循环中定义的具有不同值的Python lambda函数会返回相同结果之前,我们首先了解Lambda。
Python Lambda
Lambda表达式允许定义匿名函数。lambda函数是一个没有名称的匿名函数。让我们看看其语法-
lambda arguments: expressions
关键字 lambda 定义了一个 lambda 函数。一个 lambda 表达式可以包含一个或多个参数,但是只能有一个表达式。
示例
让我们看一个示例
myStr = "Thisisit!"
(lambda myStr : print(myStr))(myStr)
输出
Thisisit!
在循环中定义具有不同值的Python lambda表达式都会返回相同的结果
现在让我们来理解为什么在循环中使用不同值定义的Python lambda表达式会返回相同的结果。
假设我们要找到一个数的平方。使用for循环定义几个不同的lambda表达式 −
squares = []
for a in range(5):
squares.append(lambda: a**2)
这给出了一个列表,其中包含5个计算a**2的lambda函数。当调用时,它们应该返回0、1、4、9和16。然而,实际上它们都返回16,如下所示−
squares = []
for a in range(5):
squares.append(lambda: a**2)
print(squares[2]())
输出
16
现在,尝试用其他值运行。结果会相同−
squares = []
for a in range(5):
squares.append(lambda: a**2)
print(squares[4]())
输出
16
你得到类似的输出是因为x不是局部于lambda函数,而是在外部作用域中定义的,当lambda被调用时访问它,而非在定义时。
循环结束时,x的值为4,因此所有的函数现在返回4的平方,即16。通过改变x的值来验证这一点,并观察lambda函数的输出如何变化。
squares = []
for a in range(5):
squares.append(lambda: a**2)
a = 8
print(squares[2]())
为了避免这种情况,将这些值保存在与lambda函数本地变量相关联的变量中,使其不依赖于全局变量a的值。
squares = []
for a in range(5):
squares.append(lambda n=a: n**2)
在这里,n=x创建了一个新的变量n,它是局部变量,在定义lambda函数时被计算,因此它在循环中的那个点具有与a相同的值。这意味着第一个lambda函数中n的值为0,第二个lambda函数中n的值为1,第三个lambda函数中n的值为2,依此类推。
因此,现在每个lambda函数都将返回正确的结果−
squares = []
for a in range(4):
squares.append(lambda n=a: n**2)
print(squares[2]())
输出
4
让我们来看看其他一些值 −
squares = []
for a in range(5):
squares.append(lambda n=a: n**2)
print(squares[4]())
输出
16