I'm creating an array of lambda function that way (shift by n bits over a 16 bits representation but the problem is independent of the function role):
>>> lshifting=[lambda x:(x<<y) & 65535 for y in range(0,16)]
I'm expecting each lambda to use the value y had when the function was instanciated.
If I check, each lambda is a different object in memory:
>>> print (lshifting)
[<function <lambda> at 0x7f11b632fde8>, <function <lambda> at 0x7f11b632fe60>, <function <lambda> at 0x7f11b632fed8>,....
However, the behaviour is not what I expect:
>>> [x(1) for x in lshifting]
[32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768]
>>> [(1<<y) & 65535 for y in range(0,16)]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768]
I'm obviously expecting both result to be identical while all lambdas seems to have been created with a reference to the temporary y
variable and then, when used, take the last known value of this variable.
I got 2 questions:
- is this an expected behaviour ?
- what is the pythonic way to instanciate functions dynamically? (typical example is Currying)