Wired Python lambda scope (lambda closure)

think of this two code

1
2
3
4
5
6
powers = [lambda x: x**i for i in range(10)]
print(powers[3](2))
powers1 = []
for i in range(10):
powers1.append(lambda x:x**i)
print(powers1[3](2))

What do you expect the result.

The result is 512 and 512. Not 8 and 8

The reason is lambda didn't evaluate i immediately.

Python’s closures are late binding. This means that the values of variables used in closures are looked up at the time the inner function is called.

ref: https://docs.python-guide.org/writing/gotchas/#late-binding-closures

the correct implementation should be

1
2
3
4
5
6
7
8
9
10
powers = [lambda x,j=i: x**j for i in range(10)]
print(powers[3](2))
powers1 = []
def a(i):
def b(x):
return x**i
return b
for i in range(10):
powers1.append(a(i))
print(powers1[3](2))