Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: casting map object to list makes map object empty?

I have a map object that I want to print as a list but continue using as a map object afterwards. Actually I want to print the length so I cast to list but the issue also happens if I just print the contents as follows:

print("1",my_map)
print("1",list(my_map))
print("2",my_map)
print("2",list(my_map))

and this gives me the following outputs.

1 <map object at 0x7fd2962a75f8>
1 [(1000.0, 1.0, 0.01, 0.01, 0.01, 0.01, 0.01)]
2 <map object at 0x7fd2962a75f8>
2 []

Why is this happening and how can I avoid it to continue using the map and its contents?

like image 959
Atirag Avatar asked Jul 10 '17 17:07

Atirag


3 Answers

A map object is a generator returned from calling the map() built-in function. It is intended to be iterated over (e.g. by passing it to list()) only once, after which it is consumed. Trying to iterate over it a second time will result in an empty sequence.

If you want to save the mapped values to reuse, you'll need to convert the map object to another sequence type, such as a list, and save the result. So change your:

my_map = map(...)

to

my_map = list(map(...))

After that, your code above should work as you expect.

like image 98
glibdud Avatar answered Nov 02 '22 09:11

glibdud


I faced the same issue since I am using Python 3.7 version. Using list(map(...)) worked. For lower python version using map(...) would work fine, but for higher versions, map returns an iterator pointing to a memory location. So print(...) statement will give the address rather than the items itself. To get the items try using list(map(...))

enter image description here

like image 37
milky_way Avatar answered Nov 02 '22 08:11

milky_way


The reason is that the Python 3 map returns an iterator and listing the elements of an iterator "consumes" it and there's no way to "reset" it

my_map = map(str,range(5))

list(my_map)
# Out: ['0', '1', '2', '3', '4']

list(my_map)
# Out: []

If you want to preserve the map object you can use itertools.tee to create a copy of the iterator to be used later

from itertools import tee

my_map, my_map_iter = tee(map(str,range(5)))

list(my_map)
# Out: ['0', '1', '2', '3', '4']

list(my_map)
# Out: []

list(my_map_iter)
# Out: ['0', '1', '2', '3', '4']
like image 21
user2314737 Avatar answered Nov 02 '22 08:11

user2314737