# The map() function or the list comprehension?

**URL:** <https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613>\
**Category:** Python Help\
**Created:** [September 12, 2023, 4:27pm UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613 "2023-09-12T16:27:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![wchistow](https://avatars.discourse-cdn.com/v4/letter/w/977dab/32.png) [@wchistow](https://discuss.python.org/u/wchistow)\
**Post date:** [September 12, 2023, 4:27pm UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613/1 "2023-09-12T16:27:31Z")

</div>

There are two ways to apply a function to each element of an iterated object in python:

1. the `map` function:

2. the list comprehension:

In [“The Zen of Python”](http://thezenofpython.com/) there is a line:

> There should be one-- and preferably only one --obvious way to do it.

Since there are two ways to apply functions to iterated objects, it means there are good reasons for entering them. But which?

**So when is it better to use map(), and when is list comprehension?**

---

<div class="post-metadata">

**Author:** ![elis.byberi](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/elis.byberi/32/35937_2.png) [@elis.byberi](https://discuss.python.org/u/elis.byberi)\
**Post date:** [September 12, 2023, 6:41pm UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613/2 "2023-09-12T18:41:25Z")

</div>

Use a for loop:

```py
lst = [1, 2, 3, 4]
str_lst = []
for i in lst:
    str_lst.append(str(i))

```

These methods of applying functions to iterated objects have no connection to “There should be one-- and preferably only one --obvious way to do it.”

---

<div class="post-metadata">

**Author:** ![hansgeunsmeyer](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hansgeunsmeyer/32/15188_2.png) [@hansgeunsmeyer](https://discuss.python.org/u/hansgeunsmeyer)\
**Post date:** [September 12, 2023, 6:57pm UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613/3 "2023-09-12T18:57:41Z")

</div>

I think Python has evolved since those early days and many things are no longer that obvious (while others have become more obvious perhaps). For this example, imo it’s purely a question of personal preference or style - or what you happen to find more obvious. The rationale for [list comprehensions](https://peps.python.org/pep-0202/) was:

> List comprehensions provide a more concise way to create lists in situations where `map()` and `filter()` and/or nested loops would currently be used.

Your code snippet I think does illustrate that with `[i + 1 for i in lst]` which is definitely more readable than the map + lambda variant. So it’s a more a matter of “Readability counts” 🙂

---

<div class="post-metadata">

**Author:** ![flyinghyrax](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/flyinghyrax/32/12394_2.png) [@flyinghyrax](https://discuss.python.org/u/flyinghyrax)\
**Post date:** [September 12, 2023, 10:36pm UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613/4 "2023-09-12T22:36:44Z")

</div>

I will second @hansgeunsmeyer on readability being the biggest thing. On any “serious”\[1\] project code will be read more often than written, so I try to aim for whatever seems clearest in a particular situation.

Personally I find that I use comprehensions more often, especially for small expressions where I’d need a lambda with map.

* * *

1. Having a team with multiple developers, or a project lifespan long enough that the “other developer” trying to read and understand your code is… future you. 😉

---

<div class="post-metadata">

**Author:** ![kknechtel](https://avatars.discourse-cdn.com/v4/letter/k/e47c2d/32.png) [@kknechtel](https://discuss.python.org/u/kknechtel)\
**Post date:** [September 13, 2023, 9:34am UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613/5 "2023-09-13T09:34:38Z")

</div>

It would be nice if there were only one “obvious way to do it”, in general, but this is almost always a pipe dream. Different people will find different things obvious. This rule is meant more for the language designers than it is for programmers: when there is a common task that needs a few lines of code, and people write the code in different ways, and every way takes a little bit of thought… then this is a suggestion to make the language give some more explicit support. Even if everyone does it the same way, it shouldn’t seem too abstract. Following this principle is how we get nice conveniences such as `random.choice`.

As for `map` vs. list comprehensions, this is my personal guidance:

List comprehensions are usually preferred.

Consider `map` when:

- the function you want to apply already exists (especially if it is a builtin):

- you can write the transformation easily as a function _and_ that function needs to take multiple arguments from parallel input lists:

Especially prefer a list comprehension when you _also_ need a `filter`:

```auto
>>> # ew
>>> list(map(lambda x: x + 1, filter(lambda x: x % 3, range(10))))
[2, 3, 5, 6, 8, 9]
>>> # much easier
>>> [x + 1 for x in range(10) if x % 3]
[2, 3, 5, 6, 8, 9]

```

In Python 3.x, `map` is lazy. If you need or want that lazy result but want to use the list comprehension syntax, write a _generator expression_ instead:

```auto
>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> (x for x in range(10)) # This does not make a tuple.
<generator object <genexpr> at 0x7f1ddd439120>

```

The resulting “generator object” can be used in all the same basic ways as the `map` result. (There are technical differences, but they aren’t important here.)

Please don’t write an explicit loop for ordinary cases. Figuring out how to build a list from the results should be Python’s job, not yours. The `.append` method is not interesting, and the imperative logic to build the list is a distraction from the core idea: i.e., _the rule that tells you_ how the output list elements relate to the input list elements.

---

<div class="post-metadata">

**Author:** ![aivarpaalberg](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/aivarpaalberg/32/9457_2.png) [@aivarpaalberg](https://discuss.python.org/u/aivarpaalberg)\
**Post date:** [September 13, 2023, 11:41am UTC](https://discuss.python.org/t/the-map-function-or-the-list-comprehension/33613/6 "2023-09-13T11:41:56Z")

</div>

Little trip along memory lanes: [All Things Pythonic, The fate of reduce() in Python 3000  
by Guido van van Rossum](https://www.artima.com/weblogs/viewpost.jsp?thread=98196).

I agree with @kknechtel that `map` should be compared with generator expression as both are lazy. It could be important if large lists must be processed and one needs to do it only once.

I think that taking advantage of Python batteries included approach readability of using `map` can be in some cases improved as lambda can be avoided:

```python
>>> from itertools import repeat
>>> from operator import add
>>> print(*map(add, [1, 2, 3, 4], repeat(2)))
3 4 5 6
>>> from functools import partial
>>> print(*map(partial(add, 2), [1, 2, 3, 4]))
3 4 5 6
>>> from operator import mul
>>> print(*map(mul, range(10), range(10, 20)))
0 11 24 39 56 75 96 119 144 171
>>> # still ew
>>> print(*map(add, filter(lambda x: x % 3, range(10)), repeat(1)))
2 3 5 6 8 9
>>> print(*map(partial(add, 1), filter(lambda x: x%3, range(10))))
2 3 5 6 8 9

```
