Code Explanation:
1️⃣ Creating an Empty List
funcs = []
An empty list is created to store functions.
funcs → []
2️⃣ Starting the Loop
for i in range(3):
range(3) produces:
0, 1, 2
So the loop runs three times.
Iteration i
1st 0
2nd 1
3rd 2
3️⃣ Defining the Function
def f():
A function named f is created during each iteration.
The important point is that the function refers to i, which comes from the surrounding scope.
4️⃣ Returning i
return i
The function doesn't store a separate copy of i.
Instead, it closes over the variable i.
This is the main trick in this question.
5️⃣ Storing the Function
funcs.append(f)
The function object is added to funcs.
After all three iterations:
funcs → [f, f, f]
There are three function objects, but they all refer to the same loop variable i.
6️⃣ Calling All Functions
print([f() for f in funcs])
Now the functions are called.
By this time, the loop has already finished:
i = 2
Therefore each function reads the current value of i:
f() → 2
f() → 2
f() → 2
๐ฅ Why Isn't the Output [0, 1, 2]?
This is called late binding.
The functions don't capture the value of i at each iteration. They look up i when the function is called.
Loop:
i = 0 → create f
i = 1 → create f
i = 2 → create f
After loop:
i = 2
Calls:
f() → 2
f() → 2
f() → 2
✅ Final Output
[2, 2, 2]

0 Comments:
Post a Comment