2

Although documentation tells me that I should be able to convert a map object to list using list(map_object) this is not working the way I want it to.

I have a simple program:

n = int(input())
arr = map(int, input().split())
print(list(arr)) #this works
list_arr = list(arr)
print(list_arr) #doesn't work

I expect:

3
14 23 1
[14, 23, 1]
[14, 23, 1]
>>>

But I get:

3
14 23 1
[14, 23, 1]
[]

Any thoughts why?

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
arpi
  • 31
  • 2
  • 2
    `map` is one time consumable. It is already used in the first print, hence it's value is exhausted. You have to assign to some variable prior to printing. – Austin May 12 '19 at 03:20
  • Thanks Austin & DYZ! Yes that worked perfectly fine. – arpi May 12 '19 at 03:34
  • Hi @arpi I have tried to summarize whatever is present on the comments in my answer below please take a look :) – Devesh Kumar Singh May 12 '19 at 12:31

4 Answers4

2

As already mentioned in the comments map gives you an iterator, which you can only consume, or iterate through once, after which the iterator is empty, which is what happens when you did print(list(arr))

Instead assign your list(arr) to a variable, like list_arr = list(arr) and then you can use that in the subsequent code

In [144]: n = int(input())                                                                                                                                                        
3

In [145]: arr = map(int, input().split())                                                                                                                                         
14 23 1
#list_arr can be used for subsequent code, you have consumed arr completely
In [146]: list_arr = list(arr)                                                                                                                                                    

In [147]: print(list_arr)                                                                                                                                                         
[14, 23, 1]
#Iterator is empty after using it once
In [148]: print(list(arr))                                                                                                                                                        
[]
Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40
1

As commented map is one time consumable, so you can do something like so:

n = int(input())
arr = map(int, input().split())
list_arr = list(arr)
print(list_arr) #this works

And you can use the list_arr value many times.

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
-1

Once you will:

  • Learn/know about how Python generator works;

  • Write/create your own generators.

You will easily figure out this problem (looks strange but very useful and simple).

Thanks to yield keyword & StopIteration exception & some magic methods as these play great roles in writing our own generator.

Python 3.6.7 (v3.6.7:6ec5cf24b7, Oct 20 2018, 03:02:14) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> arr = [1729, 67, 92]
>>> gen = map(str, arr)
>>> 
>>> # 1st item
... 
>>> gen.__next__()
'1729'
>>> 
>>> # 2nd item
... 
>>> gen.__next__()
'67'
>>> 
>>> # 3rd item
... 
>>> gen.__next__()
'92'
>>> 
>>> # This will not work (Exception beacause no more items are in generator, over)
... 
>>> gen.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> 

So if you will focus on below kind of examples, you will be confused (1st time).

>>> arr2 = list(gen)
>>> arr2
['1729', '67', '92']
>>>
>>> # Generator has already been iterated, so no more items
...
>>> gen.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
>>> arr2 = list(gen)
>>> arr2
[]
>>> 

Just for references, have a look at below links:

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
hygull
  • 8,464
  • 2
  • 43
  • 52
-2

Simply, you can not do like: list_arr = list(arr). Because as mentioned by the above answers, it already consumes.

One way to workaround this, then you have to get each member and create a new object.

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
  • 1
    On the contrary, that's exactly how one _should_ do: convert the iterator into a list. – DYZ May 12 '19 at 04:09