python易错点之lambda及for循环内嵌函数
我们来看一下下面这段代码,预期一下它的运行结果
r=[]
for x in range(10):
r.append(lambda:x**2)
print(r[0]())
print(r[1]())
print(r[2]())
预期结果:0 1 4
实际结果:81 81 81
为什么会出现这种情况呢?
这是变量作用域带来的问题,在上面的代码中变量x是在外部作用域中定义的,对lambda表达式而言不是局部变量,从而导致出现了错误。
上面代码的等价代码如下:
r=[]
for x in range(10):#在循环中只有一个变量x,每次循环只是改变x的值
def fun():#循环创建10个匿名函数
return x**2
r.append(fun)
print(r[0]())
print(r[1]())
print(r[2]())
上面代码的含义就是循环创建10个函数,然后把函数分别装入列表r,在函数调用之前,已经循环创建了10个函数,此时x已经修改为了9,而fun函数中有没有定义x变量,所以当调用函数时会使用for循环中的变量。这样就会导致出错,这就是变量作用域所导致的问题。如何来写正确的代码呢?看下边这个代码。
r=[]
for x in range(10):
r.append(lambda n=x:n**2)
print(r[0]())
print(r[1]())
print(r[2]())
等价代码为
r=[]
for x in range(10):
def fun(n=x):
return n**2
r.append(fun)
print(r[0]())
print(r[1]())
print(r[2]())
在这个代码中循环创建函数时,每创建一个函数,就使用一个变量n将x的值保存,这样在调用函数的时候就不会出现上上述的问题。