How to Simplify Your Python Code with map()
How to Simplify Your Python Code with map()
How to Simplify Your Python Code with map()
The map
Function in Python
Definition
Python has a wide range of built-in functions, one of them being the map
function.
The map
function applies a given function to each element of an iterable (list, tuple, set) and returns a new iterator with the resulting values.
The map
function is useful when we need to process an iterable, and using this function allows us to write code that is very concise, clear, and easy to understand. Instead of writing complex for
loops, we can simply call map
, which will quickly give us the result.
The signature of the map
function is shown below:
map
(function, iterable, *list_of_iterables)
Examples
To begin with, let’s explore a simple example to illustrate how this function works.
In the example below, we have a short program that processes a list of elements to extract numeric values (including those written as strings).
At first, we’ll write the algorithm using a for
loop.
elements = [1, "2", "three", 4, 5, "six", "7", 8, 9]
processed_list = []
for elem in elements:
try:
parsed_num = int(elem)
except ValueError:
pass
else:
processed_list.append(parsed_num)
print(processed_list)
Running the code above results in the following output:
[1, 2, 4, 5, 7, 8, 9]
Simple Map
We can rewrite the same algorithm of extracting numbers and converting the string-represented numbers using the map
function:
elements = [1, "2", "three", 4, 5, "six", "7", 8, 9]
def get_number(num):
try:
return int(num)
except ValueError:
return None
processed_list = list(map(get_number, elements))
print(processed_list)
If we run this program, we’ll get a slightly different result than above, because when a value in the list cannot be converted from string
to int
, we’ll get a ValueError
exception, and the get_number
function will return None
.
[1, 2, None, 4, 5, None, 7, 8, 9]
To exclude the None
values from the list, we’ll slightly change the way we read the values returned from map
. We’ll use a list comprehension to store in the final list processed_list
only the values that are different from None
.
processed_list = [number for number in map(get_number, elements) if number is not None]
If we make the modification above and run the program, we’ll get the following result:
[1, 2, 4, 5, 7, 8, 9]
Map with Lambda
We can use the map
function in combination with lambda
for even more concise code. We can rewrite the code above as follows:
elements = [1, "2", "three", 4, 5, "six", "7", 8, 9]
processed_list = list(map(lambda x: int(x) if str(x).isdigit() else None, elements))
print(processed_list)
This code, again, will return the list with None
values instead of trei
and six
:
[1, 2, None, 4, 5, None, 7, 8, 9]
If we want to filter out these values, we can use the same mechanism as above:
elements = [1, "2", "three", 4, 5, "six", "7", 8, 9]
processed_list = [elem for elem in map(lambda x: int(x) if str(x).isdigit() else None, elements) if elem]
print(processed_list)
Although in this case the readability of the code is actually reduced, what we wanted was to illustrate how we can use the map
function in different scenarios.
Map with Multiple Lists
The map
function also allows using the same function on elements from multiple lists instead of just one. Let’s explore a simple example where we combine 3 lists of random values to generate colors in RGB format.
import random
reds = [random.randrange(0, 255) for _ in range(5)]
greens = [random.randrange(0, 255) for _ in range(5)]
blues = [random.randrange(0, 255) for _ in range(5)]
colors = list(map(lambda R, G, B: (R, G, B), reds, greens, blues))
print(colors)
The result of this program will be as follows:
[(141, 214, 234), (34, 5, 145), (176, 195, 60), (73, 4, 240), (24, 232, 189)]
Note: if the sizes of the lists are different, the map
function will iterate as long as the smallest list contains elements. Thus, the lists with more elements will not be processed completely.
Conclusion
The map
function is not a direct alternative to traditional for
and while
loops.
There are cases when it makes sense to use map
and other cases when it makes sense to use for
.
We need to understand that map
is just another tool in our toolbox, and, when used correctly, it can simplify and improve our code.
However, if misused, it can introduce problems that are difficult to spot.
A clear advantage of the map
function compared to for
and while
loops is efficiency. The implementation of map
is written in C, which means that, by default, it will run faster and more efficiently than any loop we write ourselves.
Another advantage is that map
returns an iterator
instead of a list
, which means the values are generated one by one, on demand, instead of blocking code execution until all elements in the list are generated.