Unexpected behaviour of lambda in a for loop | Sololearn: Learn to code for FREE!
New course! Every coder should learn Generative AI!
Try a free lesson
+ 1

Unexpected behaviour of lambda in a for loop

There is a code. https://code.sololearn.com/c2nZ0ZFihjRX/#py Why is values of list members different when they are printed in a for loop and when they are printed separately? Why is the last value obtained in the loop printed?

27th Apr 2020, 3:06 AM
Vladimir {Tomsk}
Vladimir  {Tomsk} - avatar
3 Answers
+ 6
When you are executing lambdas in a for loop you are changing "i" variable, so its result is changing. But when you execute lambdas separately variable "i" is not changing, its value remains unchanged from the previous for loop, so result of the lambda is also not changed. In the first for loop you create a list of absolutely identical lambda expressions which will return the sum of its argument and "i" variable at the moment of their invocations (and not at the moment of the lambda creation!!!). You just store references to the lambdas. Values of "i" aren't stored in lambdas. in line #6 "i" variable has value from the last iteration of the previous loop which is 99. lambda returns x + i = 3 + 99 = 102 in the line #7 variable "i" remains unchanged, so result will be the same. but in line #10 "i" iterates from 0 to 40 with step 10, so results of lambda invocations will be different as "i" is changed. The same for the remaining lines. If you want to capture the value of "i" in lambdas at the moment of their creation just assign "i" as default value to the second argument of the lambdas like this: lst.append(lambda x, i = i: x + i)
27th Apr 2020, 5:30 AM
andriy kan
andriy kan - avatar
+ 4
Because when called outside, the loop has already ended, so i hold the last range value ^^ You need closure to avoid this, by defining a lambda factory wich get your 'i' as argument... Puth this at start of your code: def gen_lambda(i): return lambda x: x + i ... and update your list initializations(s) as for the first: for i in range(100): #lst.append(lambda x: x + i) lst.append(gen_lambda(i)) Tadaaa! The output should now be as you're expecting ;) Vladimir {Tomsk} more about closures in this link: http://zetcode.com/JUMP_LINK__&&__python__&&__JUMP_LINK/python-closures/
27th Apr 2020, 5:44 AM
visph
visph - avatar
+ 1
Thanks for explaining, andriy kan , visph ! I've changed a variable in the second for loop. A result changed.
27th Apr 2020, 6:16 AM
Vladimir {Tomsk}
Vladimir  {Tomsk} - avatar