Python Gotcha, Nested Lambda to the Rescue
Posted: July 15th, 2010 | Author: ryan | Filed under: Uncategorized | View Comments*Note: This has been sitting sitting around as a draft for quite awhile. I’m finally posting it because it came up recently; luckily this time I was prepared.
This was brought to my attention by Jason Yan of Disqus.
Consider the following code fragment. What’s is it’s output?
1 2 3 4 | num_funcs = [] for i in xrange(0, 101): num_funcs.append(lambda x: x + i) print num_funcs[10](20) |
If you guessed 30, look again and consider the value of i during the print statement. It’s value will be 100.
What is num_funcs[10]? Clearly it is a lambda function. More importantly, it is a lambda function which has not yet been evaluated. Now consider again, the value i. What’s the the output? Hopefully you see that it is not 30, but rather 120. If you’re still unsure why that is true, let’s code the loop in such a way which will produce the expected output. Namely we would like num_funcs[n](20) to evaluate to n+20.
The trick here, is to force i to be the iteration value at the time of the append, rather than letting it persist as a variable until the print statement. To do this we simply close over the original anonymous function with another, thus establishing deeper scope and hence forcing i to be evaluated at the time of the append, like so.
1 2 3 4 5 | num_funcs = [] for i in xrange(0, 101): func = (lambda j: (lambda x: x + i))(i) num_funcs.append(func) print num_funcs[10](20) |
Note that I’ve the argument to the outer lambda is called j, but we are passing i.
This is a little tricky, because it is so subtle. Don’t get burned.




Leave a Reply