List comprehension + lambdas - strange behaviour

Raymond Hettinger python at rcn.com
Thu May 6 16:25:23 EDT 2010


On May 6, 9:34 pm, Artur Siekielski <artur.siekiel... at gmail.com>
wrote:
> Hello.
> I found this strange behaviour of lambdas, closures and list
> comprehensions:
>
> >>> funs = [lambda: x for x in range(5)]
> >>> [f() for f in funs]
>
> [4, 4, 4, 4, 4]
>
> Of course I was expecting the list [0, 1, 2, 3, 4] as the result. The
> 'x' was bound to the final value of 'range(5)' expression for ALL
> defined functions. Can you explain this? Is this only counterintuitive
> example or an error in CPython?

Try binding the value of x for each of the inner functions:

>>> funs = [lambda x=x: x for x in range(5)]
>>> [f() for f in funs]
[0, 1, 2, 3, 4]

Otherwise, the 'x' is just a global value and the lambdas look it up
at when the function is invoked.  Really, not surprising at all:

>>> x = 10
>>> def f():
...	return x
...
>>> x = 20
>>> f()
20


Raymond




More information about the Python-list mailing list