## Monday, November 12, 2012

### lambda default parameters

Making lambdas behave nicely by using default parameters

>>> [c() for c in [(lambda: i) for i in range(10)]]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

>>> [c() for c in [(lambda a=i: a) for i in range(10)]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

1. Note to self: This is mostly to solve really basic closure problems without using a wrapper function.

2. I've just been banging my head over this for an hour. Do you have any idea what the heck is going on?

3. It becomes clear as you unroll things. First let's convert the lambda to a def, and the list comprehension to a for loop:

cs = []
for x in range(10):
i = x
def c():
return i
[c() for c in cs]

Now lets flatten out the for loop:

i = 1
def a1():
return i
i = 2
def a2():
return i
i = 3
def a3():
return i
#...
[c() for c in [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]

Hopefully now it is obvious: the function is returning the value of the variable i at the time it is called. What the function is told to return is the VARIABLE i, not it's value at the time of function definition.

The disassembler may also be helpful here:

>>> import dis
>>> dis.dis(lambda: i)