Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting confused with lambda and list comprehension

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

like image 841
avasal Avatar asked Feb 09 '12 05:02

avasal


People also ask

Can you use lambda in list comprehension?

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.

What is the difference between list comprehension and lambda?

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.

Which is faster lambda or list comprehension?

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.

How do you write a lambda function in a 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.


1 Answers

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.

like image 148
Michael J. Barber Avatar answered Sep 27 '22 22:09

Michael J. Barber