Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary comprehension with inline functions

I need to store functions in a dictionary, each function depending on its key, lets say, for a key 1 the lambda function associated is lambda s: s * A[1]. I tried with dict comprehension but it seems that the inline functions ends defined with the last value of the loop.

d = {k, lambda s: s * A[k] for k in range(n)}  # e.g. n = 4

After that all lambda functions created are declared with A[3] instead of A[0], A[1], A[2] and A[3]. What's wrong with this code?

like image 465
Alejandro Sazo Avatar asked Jul 15 '15 04:07

Alejandro Sazo


2 Answers

A way to fix it is to change the code to:

d = {k: lambda s, k=k: s * A[k] for k in range(n)}

Without the binding, Python looks up the "current" k when each lambda is called, which is always n-1 in the original code.

like image 78
YS-L Avatar answered Nov 15 '22 18:11

YS-L


The issue occurs, because the contents of the lambda function are not executed until the lambda function is executed.

Hence, whenever you are trying to call lambda function, it works on the latest value of k (if you do del k and try to call the lambda function you should get an error).

The answer by @YS-L should be good for you.

Another way to do it, would be to make the value of the dictionaries a bound method ,binding the value of k. Example -

>>> d = {k:(lambda k,s: s * A[k]).__get__(k) for k in range(n)}
>>> d
{0: <bound method int.<lambda> of 0>, 1: <bound method int.<lambda> of 1>, 2: <bound method int.<lambda> of 2>, 3: <bound method int.<lambda> of 3>}
>>> A
[1, 2, 3, 4]
>>> d[0](1)
1
>>> d[1](1)
2
>>> d[2](1)
3
>>> d[3](1)
4
like image 32
Anand S Kumar Avatar answered Nov 15 '22 16:11

Anand S Kumar