Problem#
What does the below code snippet print out? How can we fix the anonymous functions to behave as we’d expect?
1
2
3
4
5
6
functions = []
for i in range(10 ):
functions. append(lambda : i)
for f in functions:
print(f())
Solution#
Method 1 - Using default argument at creation#
The given code snippet will print the number 9 ten times. This happens because the anonymous functions (lambdas) capture the variable i
by reference. When the functions are eventually called in the print loop, they all refer to the final value that i
held in the for loop, which is 9.
To fix the anonymous functions so they each capture the value of i
at the time they are created, you can use a default argument in the lambda expression. This way, the value of i
will be evaluated and stored at the time the lambda is defined. Here’s the modified code:
Code#
Python
In This Version, Each Lambda Function Is Given a Default Argument Equal to the Current Value Of `i` during Each Iteration of the Loop. as a Result, When the Lambdas Are Later Called, They Print the Value That `i` had When the Lambda Was Created. the Output Will Be:
Python
Thus, the Problem Is Solved by Making a Small but Critical Change to the Lambda Expression to Capture the Loop Variable Properly.
Java
To Fix This, We Need Each Lambda to Capture the Value Of `i` at the Time It Is Created. This Can Be Done by Introducing a Final Variable Inside the Loop:
Java
1
2
3
4
5
6
functions = []
for i in range(10 ):
functions. append(lambda i= i: i) # i is captured as a default argument
for f in functions:
print(f())
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9
1
2
3
4
##### Java
Here's how the code might look if it were written in Java using anonymous classes or lambdas:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.*;
import java.util.function.Supplier;
public class Main {
public static void main (String[] args) {
List< Supplier< Integer>> functions = new ArrayList<> ();
for (int i = 0; i < 10; i++ ) {
functions.add (() -> i);
}
for (Supplier< Integer> f : functions) {
System.out .println (f.get ());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.*;
import java.util.function.Supplier;
public class Main {
public static void main (String[] args) {
List< Supplier< Integer>> functions = new ArrayList<> ();
for (int i = 0; i < 10; i++ ) {
final int value = i;
functions.add (() -> value);
}
for (Supplier< Integer> f : functions) {
System.out .println (f.get ());
}
}
}
Complexity#
⏰ Time complexity: O(1)
for running 10 iteration
🧺 Space complexity: O(1)
for capturing 10 integer values in lambda function