Reviewed by Aditya Kumar · Last reviewed 2026-03-24
The code will produce [8, 8, 8, 8, 8] . This is due to Python's behavior of capturing variables by reference in closures (like lambdas), combined with "late binding"—the variable's value is looked up…
This easy-level Python/Coding question appears frequently in data engineering interviews at companies like Gartner. While less common, it tests deeper understanding that distinguishes strong candidates.
Start by clearly defining the core concept being asked about. Interviewers want to see that you understand the fundamentals before diving into implementation details. Structure your answer with a definition, then explain the practical application with a concise example. The expert answer includes a code example that demonstrates the implementation pattern.
The code will produce [8, 8, 8, 8, 8]. This is due to Python's behavior of capturing variables by reference in closures (like lambdas), combined with "late binding"—the variable's value is looked up at the time the inner function is executed, not when it's defined.
[8, 8, 8, 8, 8]?[lambda x: x i for i in range(5)] creates a list of five distinct lambda functions. Each lambda is defined as lambda x: x i.i at the moment of their creation. Instead, they store a reference to the variable i from their enclosing scope (the list comprehension's scope).for i in range(5) loop has completed. The variable i has iterated through 0, 1, 2, 3, 4 and its final value in the enclosing scope is 4.[f(2) for f in ...] then iterates through the list of these five lambda functions. When f(2) is called for any of these functions, it looks up the current value of i in its enclosing scope.i is now 4 for all functions, every f(2) effectively becomes lambda x: x 4 evaluated with x=2, resulting in 2 4 = 8.[0, 2, 4, 6, 8] (where each f(2) would be 20, 21, ..., 2*4), you need to "bind" the value of i at the time each lambda is created. This is commonly done using a default argument:
[f(2) for f in [lambda x, i=i: x * i for i in range(5)]]
Here, i=i as a default argument causes the current value of the outer i to be evaluated and bound to the inner i parameter for each lambda at the time of its definition. Default arguments are evaluated once when the function is defined, effectively capturing the value.
This "closure bug" is a classic in Python and JavaScript. In data engineering, similar issues can arise when dynamically creating functions or User-Defined Functions (UDFs) within loops (e.g., in PySpark), where variables from the driver program's scope might be captured by reference, leading to unexpected behavior if their values change before the UDFs are executed on worker nodes.
Pro-Move: Know the fix. Red Flag: Unaware of closure capture.
Some links below are affiliate links. If you buy through them we may earn a small commission at no extra cost to you — it helps keep DataEngPrep free.
According to DataEngPrep.tech, this is one of the most frequently asked Python/Coding interview questions, reported at 1 company. DataEngPrep.tech maintains an editor-reviewed database of 1,863 data engineering interview questions across 7 categories.