As of Python 2.1, the lambda keyword become a whole lot more useful. Instead of having to pass in each variable value, Python is able to reference variables from the containing containing scope.
For instance, let’s say we have a function called shout(f), which calls its parameter f and prints the result:
>>> def shout(f): ... print f() ...
In the olden days, if you wanted to shout the numbers 10 through 12, you could pass a lambda function to shout, like this:
>>> for n in range(3): ... shout(lambda n=n: n+10) ... 10 11 12
While that syntax still works, with Python 2.1 and later, we are able to omit the n=n and write:
>>> for n in range(3): ... shout(lambda: n+10) ... 10 11 12
However, the two forms of lambda are not quite equivalent. Omitting the n=n causes the lambda to refer to the variable in the stack frame of the function that called the lambda. Consider what happens when we change the value of n after we make the lambda function, but before we call it:
>>> l = [] >>> for n in range(3): ... l.append(lambda: n+10) ... >>> for f in l: ... shout(f) ... 12 12 12 >>>
Putting in the n=n causes the value of n to be copied at the time the lambda function is created, which is exactly what we want in this case:
>>> l = [] >>> for n in range(3): ... l.append(lambda n=n: n+10) ... >>> for f in l: ... shout(f) ... 10 11 12 >>>
I found this little wrinkle while working on a multi-threaded application. One thread was producing lambda functions in a loop, and another thread was calling them – some before the loop was finished, and some after.