In Python 3.x, map
doesn't return a list object, instead it returns an iterator.
Return an iterator that applies function to every item of iterable, yielding the results.
Basically, it doesn't process all the elements of the iterable passed immediately. It just processes one at a time, whenever asked for it.
In your case, all the elements from the range
objects are processed one by one and when all of them are processed, the iterator object returned by map
is exhausted (there is nothing else left to be processed). That is why you are getting empty list, when you do list(squares)
the second time.
For example,
>>> squares = map(lambda x: x**2, range(10))
>>> next(squares)
0
>>> next(squares)
1
>>> next(squares)
4
>>> next(squares)
9
here, we have just processed the first four items, on demand. The values were not calculated before-hand, but the lambda
function is called with the next value from the iterator passed to squares (range(10)
), when you actually did next(squares)
and the value is returned.
>>> list(squares)
[16, 25, 36, 49, 64, 81]
now, only the rest of the items in the iterator are processed. If you try to get the next item,
>>> next(squares)
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
since the squares
is exhausted, StopIteration
is raised and that is why list(squares)
is not getting any elements to process and returns an empty list.