Python Forum

Full Version: List comprehension and Lambda
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Let's think easy case. Use the map function like this:

test = map(lambda x: x, [1, 2, 3])
This gives us an iteratable object. To process this:

[i for i in test]
gives us a boring result, or a list
[1, 2, 3]
.
The equivalent way by using list comprehension is simply this one.

[lambda x: x for x in [1, 2, 3]]
The list comprehension seems to compress the map function with lambda into a simple list form.

However, here is the problem.
Let's say if we want to get something closure-d, the literal way to use the map function is:

test = map(lambda x: lambda : x, [1, 2, 3])
and, we can get its result like this:

>>> [i() for i in test]
[1, 2, 3]
>>> 
This is like a lazy evaluation. Each element of the test is like a promise, which SICP tells us.
However, the may-be-equivalent list comprehension version gives us a weird result.

>>> test = [lambda : x for x in [1, 2, 3]]
>>> [i() for i in test]
[3, 3, 3]
>>> 


Wow. What we expect to get is a list [1, 2, 3], but it gives back a list [3, 3, 3].

Is this a sort of bug, or there a detailed specification?
I'm stuck with it.

Smile Thanks, regards.
test = [lambda : x for x in [1, 2, 3]]
I think the list comprehension assigns all values for x, overwriting the object that x is pointing to each time and leaves x pointing to the last object.
[i() for i in test]
when the lambda function is called it gives the object that x is pointing to which is the last object.

If it's done as a generator it will give the object that x is pointing to on each iteration.
test = (lambda : x for x in [1, 2, 3])
print([i() for i in test])
Output:
[1, 2, 3]
(Jun-08-2021, 08:09 AM)Yoriz Wrote: [ -> ]I think the list comprehension generates all the assigned values for x, overwriting x each time and leaves x pointing to the last value.
Oh, I see. I've never imagined that Python's list comprehension is implemented with a destructive, or non-functional way, even though it comes from Haskell.
(Would Haskell give the same result? I don't know now. I'll test whether.)

O.K. I'll try generator instead.

Thank you!