-1

I defined some lambdas and attempt to execute them. These are the lambda functions I have defined.

a = []
for i in range(3):
    a.append(lambda a:i+a)

When I execute the following code :

for j in range(3):
    print(a[j](0))

The results are:

2
2
2

But when I change the variable name and do the same thing:

for i in range(3):
    print(a[i](0))

I can not get the same results:

0
1
2

I don't understand why this is happening...

Adrian
  • 468
  • 2
  • 6
  • 15
zo Aoo
  • 21
  • 4

1 Answers1

1

You're not saving the variable's value inside the lambda. You're saving a variable defined outside of the lambda. It's not necessarily a global variable, but to the scope of the lambda, it is declared outside of it. When the iteration terminates, the value of i is 2. That's why when you iterate with for-loop using j, the value inside the lambda is always 2.

When you iterate on a for-loop using the i variable, you're once again changing the state of i before executing the lambda. That's why it gives you a different result.

To make the lambda get the variable's value only without keeping it dependant of any variable scope, do something like this:

a = []
for i in range(3):
    a.append((lambda k: lambda x:(k+x))(i))

lambda k: ... is used to pass the state of i to the inner lambda. It's in fact executing the function, and returning lambda x: (k+x), where k is a private variable from the lambda's scope.

Now when you try to print it using another variable, such as j, or assigning a new value to i or k:

i = 256
k = 512

for j in range(3):
    print(a[j](0))

The output is:

0
1
2
Carl HR
  • 776
  • 5
  • 12
  • 2
    A more idiomatic solution to binding a variable value to the scope of a lambda function is to pass it as the default value of a parameter. See the duplicate link for details. – blhsing Jul 15 '22 at 02:31
  • 2
    I didn't know it could be done that way. Good to know, thanks. – Carl HR Jul 15 '22 at 02:34