Why does map return a map object instead of a list in Python 3?
I think the reason why map still exists at all when generator expressions also exist, is that it can take multiple iterator arguments that are all looped over and passed into the function:
>>> list(map(min, [1,2,3,4], [0,10,0,10]))
[0,2,0,4]
That's slightly easier than using zip:
>>> list(min(x, y) for x, y in zip([1,2,3,4], [0,10,0,10]))
Otherwise, it simply doesn't add anything over generator expressions.
Getting a map() to return a list in Python 3.x
Do this:
list(map(chr,[66,53,0,94]))
In Python 3+, many processes that iterate over iterables return iterators themselves. In most cases, this ends up saving memory, and should make things go faster.
If all you're going to do is iterate over this list eventually, there's no need to even convert it to a list, because you can still iterate over the map
object like so:
# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
print(ch)
Python 3 map is returning a list of NoneType objects instead of the type I modified?
This is because, your incr_number doesn't return anything. Change it to:
def incr_number(self, incr=0):
self.number += incr
return self
Understanding the map function
map
isn't particularly pythonic. I would recommend using list comprehensions instead:
map(f, iterable)
is basically equivalent to:
[f(x) for x in iterable]
map
on its own can't do a Cartesian product, because the length of its output list is always the same as its input list. You can trivially do a Cartesian product with a list comprehension though:
[(a, b) for a in iterable_a for b in iterable_b]
The syntax is a little confusing -- that's basically equivalent to:
result = []
for a in iterable_a:
for b in iterable_b:
result.append((a, b))
Map object empties itself after converting to list
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.
Related Topics
Removing Horizontal Lines in Image (Opencv, Python, Matplotlib)
How to Create an Empty Array and Then Append to It in Numpy
Django.Db.Utils.Operationalerror Could Not Connect to Server
Write Dictionary of Lists to a CSV File
Django JSONfield Inside Arrayfield
Combining Two Series into a Dataframe in Pandas
Python Saving Multiple Figures into One PDF File
How to Output to the Same Line Overwriting the Previous Line
Running a Tkinter Form in a Separate Thread
Convert a 1D Array to a 2D Array in Numpy
Case Insensitive Flask-Sqlalchemy Query
Why Is 'Self' in Python Objects Immutable
Python Daemon and Systemd Service