In this code, the x in the lambda refers to the x in the for statement. So y[0]() returns 2:
x = 0
y = [lambda : x for x in range(3)]
y[0]()
But in this code, the x in the lambda refers to global x, so x[0]() returns global x itself:
x = [lambda : x for x in range(3)]
x[0]()
I want to know why the x in the lambda refers to the local x in the first piece of code but global x in the second piece of code.
xrefers to the globalxin both pieces of code. Indeed, there is nothing but a globalxin both pieces of code. There are no local variables here, only global variables.In the first example, the global value of
xis 2, because that was the last value assigned to it by the list comprehension. List comprehensions leak their variables into the enclosing scope as described by @wim. Since the enclosing scope here is the global scope, the variablexis leaked into global scope, overwriting the value 0 that you set earlier.In the second example, you create the list comprehension, but then assign its value to the (global) variable x. This overwrites whatever was already in x, so the value of the global variable x is now the list.
In both cases, when you call one of the functions in the list (any one!), it returns the current value of
x. You can see this here: