On Wed, 25 Nov 2015 14:51:23 +0100, Antoon Pardon wrote:

> Am I missing something?

The issue is with lambdas rather than with list comprehensions per se.

Python's lambdas capture free variables by reference, not value.

        > x = 3
        > f = lambda y: x + y
        > f(0)
        3
        > x = 7
        > f(0)
        7

The same issue applies to nested functions:

        > def foo():
        =    x = 3
        =    def f(y):
        =       return x + y
        =    print f(0)
        =    x = 7
        =    print f(0)
        = 
        > foo()
        3
        7

And also to non-nested functions (but most people expect that):

        > x = 3
        > def f(y,x=x):
        =   return x + y
        =
        > print f(0)
        3
        > x=7
        > print f(0)
        3

If you want to capture a variable by value, add a parameter with a default
value using that variable:

        > def foo():
        =    x = 3
        =    def f(y, x=x):
        =       return x + y
        =    print f(0)
        =    x = 7
        =    print f(0)
        = 
        > foo()
        3
        3

This also works for lambdas:

        > x = 3
        > f = lambda y,x=x: x + y
        > f(0)
        3
        > x = 7
        > f(0)
        3

Returning to the original expression:

        > q = [lambda x: i * x for i in range(4)]
        > q[0](1), q[3](1)
        (3, 3)
        > q = [lambda x,i=i: i * x for i in range(4)]
        > q[0](1), q[3](1)
        (0, 3)


-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to