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

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