Read a question on stack overflow sometime back with the following syntax
In [1]: [lambda: x for x in range(5)][0]()
Out[1]: 4
In [2]: [lambda: x for x in range(5)][2]()
Out[2]: 4
But i am having a hard time to understand why exactly the output of this comes as 4, my understanding is it always gives the last value of the list as output,
In [4]: [lambda: x for x in [1,5,7,3]][0]()
Out[4]: 3
but still not convinced how does this syntax ends up with the last value.
Would be very glad if i can get a proper explanation for this syntax
List Comprehension Python Vs.In Python, we also use Lambda functions to modify and manipulate lists. Lambda functions are also known as anonymous functions. Lambda functions are usually used with various built-in functions such as map() filter(), and reduce() to work on lists.
The difference between Lambda and List Comprehension. List Comprehension is used to create lists, Lambda is function that can process like other functions and thus return values or lists.
Actually, list comprehension is much clearer and faster than filter+lambda, but you can use whichever you find easier. The first thing is the function call overhead: as soon as you use a Python function (whether created by def or lambda) it is likely that the filter will be slower than the list comprehension.
Explanation: On each iteration inside the list comprehension, we are creating a new lambda function with default argument of x (where x is the current item in the iteration). Later, inside the for loop, we are calling the same function object having the default argument using item() and getting the desired value.
This isn't really about either list comprehensions or lambdas. It's about the scoping rules in Python. Let's rewrite the list comprehension into an equivalent loop:
funcs = []
for x in range(5):
def f(): return x
funcs.append(f)
funcs[0]() # returns 4
Here, we can see that we successively construct functions and store them in a list. When one of these functions is called, all that happens is the value of x
is looked up and returned. But x
is a variable whose value changes, so the final value of 4
is what is always returned. You could even change the value of x
after the loop, e.g.,
x = 32
funcs[2]() # returns 32
To get the behavior you expected, Python would need to scope the for
contents as a block; it doesn't. Usually, this isn't a problem, and is easy enough to work around.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With