9

I was working with Python, and I noticed that the map() function doesn't really seem to do much. For instance, if I write the program:

mylist = [1, 2, 3, 4, 5]
function = map(print, l)
print(function)

It provides no advantages over:

mylist = [1, 2, 3, 4, 5]
for item in mylist:
    print(item)

In fact, the second option creates fewer variables and seems generally cleaner overall to me. I would assume that map() provides advantages that cannot be seen in an example as simplistic as this one, but what exactly are they?

EDIT: It seems that some people have been answering a different question than the one I intended to ask. The developers who made Python obviously put some work into creating the map() function, and they even decided NOT to take it out of 3.0, and instead continue working on it. What essential function did they decide it served?

KnightOfNi
  • 770
  • 2
  • 10
  • 17
  • `map` is C code so it's faster – yedpodtrzitko Jun 08 '14 at 21:09
  • 1
    Note: `function = map(print, l); print(function)` is not how you would use `map` to print the elements of a list, even if using `map` for that were a good idea. You'd use `list(map(print, l))`, to exhaust the `map` iterator, rather than printing the iterator itself. – user2357112 Jun 08 '14 at 21:14
  • @user2357112: If you don't actually care about the output of `map()` and just want to consume the iterator, you'd have to use something like `consume = lambda iterator: deque(iterator, maxlen=0)`. – Blender Jun 08 '14 at 21:17
  • @Blender: If you're aware enough to avoid building a list, you're probably aware enough to not use map for this, though. – user2357112 Jun 08 '14 at 21:18
  • @user2357112 Wait, why wouldn't you use `map()` for @Blender 's example? – KnightOfNi Jun 08 '14 at 21:24
  • @Felk Could you elaborate and provide examples? – KnightOfNi Jun 08 '14 at 21:26
  • 1
    @KnightOfNi: Mostly, it comes down to the fact that `map` is not intended to be used for side effects, and people expect it not to have any. `consume(map(print, l))` is fairly straightforward, not terribly bug-prone, and not potentially memory-intensive, but it generally doesn't offer any benefit over `for x in l: print(x)`. More complex expressions in the `map` call grow unreadable, and whoever has to maintain your code probably won't like it. – user2357112 Jun 08 '14 at 21:45

4 Answers4

9

It used to be more useful back before list comprehensions. You've probably seen code like

[int(x[2]) for x in l]

Back before list comprehensions, you'd write that as

map(lambda x: int(x[2]), l)

(This was also back before map returned an iterator.)

These days, list comprehensions and generator expressions handle most of what map used to do. map is still cleaner sometimes, particularly when you don't need a lambda. For example, some people prefer

map(str, l)

over

(str(x) for x in l)
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • So, you're saying `map()` over `for/in` is more a stylistic choice? – KnightOfNi Jun 08 '14 at 21:13
  • @KnightOfNi: These days, pretty much. Note that `map` is for "build a sequence" or "apply a transformation" use cases; "make something happen" loops like `print`ing the contents of a list are not `map`'s role. – user2357112 Jun 08 '14 at 21:17
  • @KnightOfNi see also this topic: http://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map – timgeb Jun 08 '14 at 21:22
  • @timgeb Thanks! I'm getting a definite impression that `map()` vs an iterator/generator is very stylistic. – KnightOfNi Jun 08 '14 at 21:30
2

It can be much less verbose. Imagine you want to add + 1 to each element in a list of ints.

old_list = [1, 2, 3, 4]
new_list = []
for i in old_list:
    new_list.append(i+1)

vs.

old_list = [1, 2, 3, 4]
new_list = map(lambda x: x+1, old_list)

You say the map syntax appears much less clear to you. However, mapping is used so often in applications, that sooner you will appreciate how small and concise it is.

It really helps if you think of map as a function that takes in an input list of size N, and outputs a new list of the exact same length with a transformation done on each element. If you keep this in mind, everytime you see a map function, you know exactly what is about to happen.

You will notice that Python has some other functional programming functions such as reduce, filter, zip etc. map is part of this class of functions where although each implements a very simple function, when you combine these into a single statement you can get very powerful results. With a for loop you cannot achieve the same expressiveness so succinctly.

Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
  • I was just about to post a comment saying that the first one seemed much cleaner. Nice anticipation. Anyway, would you say that `map()` is a better choice, as indicated by https://stackoverflow.com/questions/2573135/python-progression-path-from-apprentice-to-guru?rq=1 – KnightOfNi Jun 08 '14 at 21:16
  • I used to think the `for loop` was cleaner as well. But it really helps if you think of `map` as a function that takes in an input list of size N, and outputs a new list of *the exact same length* with a transformation done on each element. If you keep this in mind, everytime you see a `map` function, you know exactly what is about to happen. – Martin Konecny Jun 08 '14 at 21:18
1

One very common use is converting types of an entire list

>>> myList = ['1', '2', '3', '4']  # currently strings
>>> myList
['1', '2', '3', '4']

>>> map(int, myList)   # now ints
[1, 2, 3, 4]

>>> map(float, myList)  # now floats
[1.0, 2.0, 3.0, 4.0]

Another very common use is passing a list through some function

>>> def addToFive(x):
>>>     return x + 5

>>> l = [1,2,3,4,5]

>>> map(addToFive, l)
[6, 7, 8, 9, 10]
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Yes, but that's not too much easier than simply using the above method. – KnightOfNi Jun 08 '14 at 21:12
  • At the end of the day, you can use `for` loops, list comprehensions, or `map`s for many of the same uses. It's up to you whatever you are comfortable with, is easy to read/understand, and is Pythonic! – Cory Kramer Jun 08 '14 at 21:16
  • OK, so there aren't any advantages at all? I read something about `map()` buffering one list with values of `None` to make it equal in length to another... so is it just better error handling and whatnot? – KnightOfNi Jun 08 '14 at 21:21
1

According to map's documentation: "Return an iterator that applies function to every item of iterable, yielding the results."

No packed code:

def square(x):
    return x**2

def calculist(lista):
    for n in lista:
        yield square(n)

numbers = [i for i in calculist(range(10))]

One line code:

numbers = map(lambda x: x**2, range(10))

As filter, beyond others, map is a built-in function with focus on functional programing. It may be useful for hacks and tricks, because it shorten the code, but can be a bad idea for large projects in use.

You can get more fun on Functional Programming HOWTO from official doc.

Mauro Baraldi
  • 6,346
  • 2
  • 32
  • 43
  • I know what it does, but what besides the fact that it's shorter makes it BETTER? Also, your first program is so long as to be unrealistic - in fact, I don't think it even works. – KnightOfNi Jun 08 '14 at 23:51
  • Sorry, there was some errors indeed. It's not better, this is a another way to solve the same problem, applying a different programing paradigm, the functional. As Python is multi-paradigm, remove this features, could limit the features language to paradigm. – Mauro Baraldi Jun 09 '14 at 10:28