What does a list comprehension do (was: Late-binding of function defaults (was Re: What is a function parameter =[] for?))

Nobody nobody at nowhere.invalid
Thu Nov 26 06:13:44 EST 2015


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)





More information about the Python-list mailing list