dolaameng dolaameng - 4 months ago 10
Python Question

How does a lambda function refer to its parameters in python?

I am new in Python. My task was quite simple -- I need a list of functions that I can use to do things in batch. So I toyed it with some examples like

fs = [lambda x: x + i for i in xrange(10)]


Surprisingly, the call of

[f(0) for f in fs]


gave me the result like
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
. It was not what I expected as I'd like the variable
i
has different values in different functions.

So My question is:


  1. Is the variable
    i
    in lambda global or local?

  2. Does python has the same concept like 'closure' in javascript? I mean does each lambda here holds a reference to the
    i
    variable or they just hold a copy of the value of
    i
    in each?

  3. What should I do if I'd like the output to be
    [0, 1, .....9]
    in this case?


Answer

It looks a bit messy, but you can get what you want by doing something like this:

>>> fs = [(lambda y: lambda x: x + y)(i) for i in xrange(10)]
>>> [f(0) for f in fs]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Normally Python supports the "closure" concept similar to what you're used to in Javascript. However, for this particular case of a lambda expression inside a list comprehension, it seems as though i is only bound once and takes on each value in succession, leaving each returned function to act as though i is 9. The above hack explicitly passes each value of i into a lambda that returns another lambda, using the captured value of y.

Comments