9
votes

Possible Duplicate:
Use value of variable in lambda expression

I'm working with python and trying to isolate a problem I had with lambda functions.

From the following code I was expecting to create two lambda functions, each getting a different x, and the output should be
1 2

but the output is 2 2

Why? And how can I make two different functions? Using def?

def main():
    d = {}
    for x in [1,2]:
        d[x] = lambda : print(x)

    d[1]()
    d[2]()


if __name__ == '__main__':
    main()
3
Bad use of lamba. It just returns the turn value of print which is None. Print is supposed to be a command and not an expression. - jamylak

3 Answers

20
votes

The body of the lambda in your code references the name x. The value associated with that name is changed on the next iteration of the loop, so when the lambda is called and it resolves the name it obtains the new value.

To achieve the result you expected, bind the value of x in the loop to a parameter of the lambda and then reference that parameter, as shown below:

def main():
    d = {}
    for x in [1,2]:
        d[x] = lambda x=x: print(x)

    d[1]()
    d[2]()


if __name__ == '__main__':
    main()

>>> 
1
2
8
votes

Looks like work for partial.

from functools import partial 
def main():
    d = {}
    for x in [1,2]:
        d[x] = partial(lambda x: print(x), x=x)

    d[1]()
    d[2]()


if __name__ == '__main__':
    main()
4
votes

This will fix it. It is because the x is directly bound to the lambda.

def create_lambda(x):
    return lambda : print(x)

def main():
    d = {}
    for x in [1,2]:
        d[x] = create_lambda(x)

    d[1]()
    d[2]()


if __name__ == '__main__':
    main()