+ 2

Question about lambdas in python

The following code produces 222. Why? def bla(): return [lambda x:i*x for i in range(3)] for b in bla(): print(b(1), end='') I thought it should produce 012, as bla() returns a list of three functions that do 0*x, 1*x and 2*x respectively. Then in the for-loop we pass 1 to them, and should get 012... But we get 222, why?

12th Apr 2017, 12:20 PM
khaozavr
khaozavr - avatar
12 Answers
+ 5
@khao It exactly does. But by writing for b in bla() you kind of iterate through them. And remember that bla() itself does not take arguments, just returns the list of anonymous functions. Each of those functions take 1 as argument, because of b(1). And since those lambdas were not told to return anything, they just assume the last generated value, each. And this is what you print.
12th Apr 2017, 2:23 PM
Kuba SiekierzyƄski
Kuba SiekierzyƄski - avatar
+ 6
Only the last item in lambda is returned. It equals 2 and is printed 3 times in a row. If you used b(5) it should print 101010
12th Apr 2017, 1:26 PM
Kuba SiekierzyƄski
Kuba SiekierzyƄski - avatar
+ 6
@merkrafter Yes, exactly. And then it is iterated through, but does not specifically return anything. When done executing it just assumes the last value and this is the one that is printed.
12th Apr 2017, 2:37 PM
Kuba SiekierzyƄski
Kuba SiekierzyƄski - avatar
+ 4
I think its because x is string,so it will concat it 3 times
12th Apr 2017, 12:26 PM
Meharban Singh
Meharban Singh - avatar
+ 4
@khao, What would you like it to return? bla() itself does not take any argument, but is of a function class. If you call one of its instances (for b in bla()) AND you provide an argument (1), it goes to that function and carries out its iteration. When it's done, it returns the last value it reached, becuase you told it to return a value, not the function itself.
12th Apr 2017, 1:51 PM
Kuba SiekierzyƄski
Kuba SiekierzyƄski - avatar
+ 2
@Kuba, I thought my bla() would contain three different lambda functions, and when I pass an argument in a for loop, it would loop through these three funcs and produce respective outputs... Your explanation makes sense, but then I don't understand why each one instance of bla() doesn't produce a list of three lambdas, but an integer?
12th Apr 2017, 2:11 PM
khaozavr
khaozavr - avatar
+ 2
@Kuba ok, now I get it. The crucial missing bit for me was that the lambdas would assume the last value because not explicitly returning anything. Thanks a lot!
12th Apr 2017, 2:26 PM
khaozavr
khaozavr - avatar
+ 1
how is x string? isn't x = 1 here?
12th Apr 2017, 12:32 PM
khaozavr
khaozavr - avatar
+ 1
I don't know the answer (yet), but if you vary that n in range(n) (in your case it's n=3) you'll get str(n-1)*n as your output. So for n=4 the output is 3333 AND: print (type(b(1))) proofes that you get integers
12th Apr 2017, 12:48 PM
merkrafter
+ 1
@merkrafter yeah, it looks as if the n lambda funcs in the list returned by bla() are all the same, namely taking the last i in range, which is n-1. The question is why...
12th Apr 2017, 12:53 PM
khaozavr
khaozavr - avatar
+ 1
@Kuba but why is only the last lambda returned?
12th Apr 2017, 1:41 PM
khaozavr
khaozavr - avatar
+ 1
So bla() does NOT return [lambda x: 0*x, lambda x: 1*x, lambda x: 2*x] but [lambda x: i*x for... and that three times, right?
12th Apr 2017, 2:25 PM
merkrafter