Search code examples
pythonlist-comprehension

map from a list comprehension?


I came across this scraping problem which itself is irrelevant but want to know if it is possible to perform map() from a list comprehension meaning the iterable be a list comprehension?

The following returns the empty list where I expected [0, 2, 4, 6, 8] :

def foo() -> list[int]:
    result: list = []
    map(result.append, [x for x in range(10) if x % 2 == 0])
    print(result)

I guess the question is could the iterable for map function itself be a list comprehension or not? This specific example isn't itself important.


Solution

  • The second argument to map can be any iterable, including a list comprehension. That's fine.

    The actual problem is that map itself returns an iterable, that doesn't do anything until it's consumed. You could put this itself in something like a for loop, like

    result: list[int] = []
    iter = map(result.append, [x for x in range(10) if x % 2 == 0])
    for x in iter:
      print(f"This is the result of result.append, which is None: {x}")
    print(result)
    

    Note that the list comprehension itself is just syntactic sugar around map and filter, but putting it in list syntax forces the iterator to be resolved to a list, rather than a lazy iterable.

    evens1 = [x for x in range(10) if x % 2 == 0]
    evens2 = list(map(filter(range(10), lambda x: x % 2 == 0), lambda x: x))
    

    Correspondingly in your own code, you could evaluate the map result to a list and then discard it immediately; that would also work.

    result: list = []
    list(map(result.append, [x for x in range(10) if x % 2 == 0]))
    #^^^
    print(result)
    

    (In the setup you show, result is expected to be identical to the input list. More generally you can use map or a list comprehension instead of iterating and using result.append, and this more functional style may be a little more compact and easier to read.)