map() vs list comprehension
map() calls a function for every element and returns a lazy iterator, while a list comprehension builds a new list right away and can filter with an if condition.
Side-by-side comparison
#What it returns
- map()
- An iterator (lazy)
- List comprehensions
- A list (right away, in memory)
Requires a function
- map()
- Yes, an existing function or lambda
- List comprehensions
- No, you write the expression directly
Filtering elements
- map()
- Needs a separate
filter() - List comprehensions
- Built in with
ifat the end
The result can only be walked once
- map()
- Yes
- List comprehensions
- No, it’s a plain list
Readability for simple transformations
- map()
- Lower, needs an extra function or lambda
- List comprehensions
- Higher, a single line
Typical use
- map()
- An existing function, lazy processing
- List comprehensions
- Short transformations, transformations with a condition
Example
#values = ["12", "7", "30"]
doubled_map = list(map(lambda v: int(v) * 2, values))
doubled_comprehension = [int(v) * 2 for v in values]
print(doubled_map)
print(doubled_comprehension)
print(doubled_map == doubled_comprehension)Definition and usage
#Both transform a collection element by element, producing a new sequence of values of the same length, as long as you’re not filtering. In both cases the original collection doesn’t change.
They differ in syntax and in when the results come into being. map(function, collection) needs an already existing function or lambda and returns an iterator: the values are produced lazily, only once you ask for them, e.g. in list() or a for loop, and you can only walk it once. A list comprehension ([expression for x in collection]) immediately creates the whole list in memory, and an optional if condition at the end filters elements without an extra call to filter().
When you already have a named function and need a lazy iterator, for example to chain it further with other iterators, map() can be convenient. In most code a list comprehension is easier to read, especially when the transformation is short or you need to add a condition. The version with parentheses, a generator expression, gives the same laziness as map().
Syntax
#map(function, iterable)
[expression for element in iterable if condition]More examples
#numbers = [1, 2, 3]
result = map(lambda n: n * n, numbers)
print(type(result).__name__)
print(list(result))
print(list(result))The iterator gets used up after the first pass. The second attempt to convert it to a list already gives an empty list.
scores = [45, 82, 67, 91, 30]
passed_comprehension = [s for s in scores if s >= 60]
passed_map_filter = list(filter(lambda s: s >= 60, map(lambda s: s, scores)))
print(passed_comprehension)
print(passed_comprehension == passed_map_filter)Good practices
#- Just need a transformation with no condition? Both options work, but a list comprehension is usually easier to read in Python.
- When you need to filter and transform at the same time, a list comprehension with
ifis shorter than combiningmap()andfilter(). - If the data is very large and you want to process it lazily without building a list, use
map()or a generator expression(expression for x in collection).
Related entries
#- map()Calls a function for every item and returns an iterator of results.
- List comprehensionsA concise way to build lists, sets, and dictionaries from other collections.
- filter()Returns an iterator of items for which a function returns a truthy value.
- lambdaA short anonymous function written as a single expression.
Spotted a mistake or missing an example? Write to us.