1

Why lambda function to get the list of values ​​i = 4 .During the call lambda, enclosing scope does not exist. The function f has finished work and returned control (the variable i does not exist).

def f():
    L = []
    for i in range(5): 
        L.append(lambda x: i ** x) 
    return L
L = f()
L[0]



def f1(N):
    def f2(X):
        return X**N
    return f2
f=f1(2) 
f (3)  
 9
g = f1(3)
g(3)
27
f(3)
9

1 Answers1

9

Python uses closures to capture references to the original variable. The lambda objects retain a reference to the i name, through which the value can be accessed. This means that the i variable continues to live on after f completes.

You can introspect this closure in the .__closure__ tuple on the lambda objects; functions have the same attribute:

>>> L[0].__closure__
(<cell at 0x1077f8b78: int object at 0x107465880>,)
>>> L[0].__closure__[0]
<cell at 0x1077f8b78: int object at 0x107465880>
>>> L[0].__closure__[0].cell_contents
4

This is also why all lambdas in your list L refer to the value 4, and not to the numbers 0 through to 4. They all refer to the same closure:

>>> L[0].__closure__[0] is L[1].__closure__[0]
True

The closure refers to the variable, not to the value of that variable at the time the closure was defined. At the end of the loop i was last set to 4, so when looking up i in the lambda closure 4 will be found, for all lambdas in your list.

If you want your lambdas to refer to the value of i during the loop, capture it in a keyword argument:

def f():
    L = []
    for i in range(5): 
        L.append(lambda x, i=i: i ** x) 
    return L

Now i is a local variable to the lambda, not a closure.

Alternatively, create an entirely new scope from which to draw the closure:

def create_lambda(i):
    return lambda x: i ** x

def f():
    return [create_lambda(i) for i in range(5)]

Now create_lambda() is a new scope with it's own local i for the lambda closure to refer to. The lambdas then each have their own closures:

>>> L[0].__closure__[0] is L[1].__closure__[0]
False

Closures refer to a variable in a specific namespace; each time you call a function a new local namespace is created, so each closure refers to i in create_lambda in a separate namespace from other calls to create_lambda.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • @user2494676: anything else you wanted to know? Any specific reason you are accepting then unaccepting my answer once in a while? – Martijn Pieters Jun 18 '13 at 13:39
  • If lambda closed, why do not they have different values ​​in each iteration? i = 4 only in the final iteration – user2494676 Jun 18 '13 at 13:45
  • 1
    @user2494676: They all refer to the *variable*. `i` is assigned `4` last. By the time the function is done, `i` is still and will remain `4`. – Martijn Pieters Jun 18 '13 at 13:46
  • @user2494676: see [Local variables in Python nested functions](http://stackoverflow.com/a/12423750) – Martijn Pieters Jun 18 '13 at 13:47
  • three functions created when i is not yet equal to four. i = 4, only when a last function. For example – user2494676 Jun 18 '13 at 13:59
  • Yes, but `i` is looked up *when you execute the function*. The closure doesn't refer to the value, it refers to the variable. When you call the lambda, `i` is 4. It may have been 0, 1, 2 or 3 before when you defined the lambda, *but it is no longer now*. – Martijn Pieters Jun 18 '13 at 14:01
  • Ok, Why is this code function f is not looking for a new variable N? – user2494676 Jun 18 '13 at 14:29
  • @user2494676: The closure is tied to a variable for a *given namespace*. Each time you run `f1()` a new namespace is created. – Martijn Pieters Jun 18 '13 at 14:32