pythonlistin-place

why does list(map(..)) return a list of None when using it with list.reverse?


Say

L = [[1,2,3],[4,5,6]]
f = lambda x: x.reverse()
K = map(f,L)
# I want [[3,2,1],[6,5,4]]

theoretically, K is a map that reverses each sublist in L.

print(K) #prints some map
print(L) #prints [[1,2,3],[4,5,6]]

So far, L is not reversed. However,

print(list(K)) #prints [None,None]
print(L)       #prints [[3,2,1],[6,5,4]]

I assume that print(list(K)) returns [None, None] since list.reverse() is an in-place function on L. However, the change is not applied when I call K, but it is applied when I insert K in an list. What is going on?


Solution

  • You're correct in identifying that list.reverse() is an in-place operation, meaning it changes the list itself and doesn't return a new list. That's why None is the output, as the reverse method doesn't return anything (its return value is None).

    The thing to understand about map is that it doesn't execute the function on the elements of the iterable until you actually iterate over the map object. The map object is a sort of promise that says "I'll do this operation when you need the result".

    In your code:

    L = [[1,2,3],[4,5,6]]
    f = lambda x: x.reverse()
    K = map(f,L)
    

    K is a map object, and the reverse operations haven't been performed yet. They're waiting to be performed when you iterate over K.

    When you do print(list(K)), it converts K to a list, which involves iterating over K, which involves running f (the reverse operation) on each element of L. That's when the sublists get reversed. But f returns None because list.reverse() returns None, so what you get is a list of Nones.

    And now when you look at L, you see that it has been reversed. That's because the reverse operation was performed on its sublists when you iterated over K.

    In summary, the changes were applied when you called list(K), not when you created K with map(f, L), and list(K) gave you [None, None] because f returns None.

    If you want to use map and a lambda function to reverse the sublists, you can do it like this:

    L = [[1,2,3],[4,5,6]]
    f = lambda x: x[::-1]  # This creates a new list that's a reversed version of x
    K = map(f,L)
    print(list(K))  # prints [[3, 2, 1], [6, 5, 4]]
    

    Here f creates a new list instead of reversing x in-place, so it has a list to return, and map(f, L) gives you the result you want. And it leaves L unchanged.