In Python, you can use the map() function to apply an operation for each element of an iterable, such as a list.
The map() function is a replacement for a for loop.
For instance, let’s square a list of numbers using the map() function instead of a for loop:
numbers = [1, 2, 3, 4, 5] squared_nums = map(lambda x: x ** 2, numbers) print(list(squared_nums))
Output:
[1, 4, 9, 16, 25]
The result is a new list of numbers, in which each element is a number from the original list squared.
Using the map() function is not restricted to lists of numbers. In Python, you can call the map() function on any iterable object.
In this guide, you are going to learn how to use the map() function in Python. We are also going to discuss whether the map() function should be used or not. You are also going to see some similar functions as well as some alternatives.
The main goal of this guide is to teach you for loop alternatives to transforming iterables and teach you the basics of functional programming.
After this guide, you know how to write Pythonic code without using a for loop.
Introduction to the map() Function
Python comes in with a bunch of built-in functions.
One of them is the map() function.
The map() function is a shorthand replacement for a for loop. It allows you to transform one iterable into another.
Using the map() function is called mapping.
The map() function maps elements from one iterable to another. It does this one by one by applying an operation to each element in the iterable.
The map() function represents a functional programming style.
As a matter of fact, to write Pythonic and readable code, you should not use the map() function.
However, the map() function is still worthwhile learning to understand the basics of functional programming. Also, the map() function is used often. Thus it does not hurt to understand how it works.
To make this tutorial a bit easier for you, it helps if you have some background with:
Although, you are going to see a quick primer to lambda functions and iterables in this guide as well.
Before jumping into the map() function, you should know why such a function exists in the first place.
Let’s start by talking about functional programming and its features.
What Is Functional Programming?
As the name suggests, functional programming means the computations are done with functions that take arguments and return results.
One of the most common programming paradigms is called functional programming.
A functional program, as the name suggests, consists of specific types of function calls.
In functional programming, a function does not modify the input. Thus, the state of the program is not altered by the functions. Instead, the functions are used to calculate new results based on the input.
A function that does not modify the input is called a pure function.
Functionally programmed programs are easier to work with because the functions are pure and thus work in isolation.
- You can develop the program easier because every function can be treated as a separate and independent entity.
- Also, debugging and testing the code becomes streamlined because you can focus on one function and leave out all the other parts of the code.
- More importantly, a functionally written program is readable and understandable. There are no confusing state changes throughout the program.
Commonly, a functional program uses lists and other types of iterables to represent data. In addition, a set of pure functions is used to transform these iterables.
A functional program is characterized by at least these three techniques:
- Mapping.
- Filtering.
- Reducing.
Each of these techniques uses a function that loops through the iterable and applies an operator to each element.
Also, notice that each of these techniques could be implemented as a regular for or while loop!
Let’s take a quick look at these techniques.
Mapping
Mapping means applying a function to each element in the iterable. The result is a new iterable with the transformed values. The original iterable remains untouched.
In Python, mapping is done using the map() function.
Learning the map() function is the main agenda of this guide.
Filtering
Filtering means applying a boolean-valued function to each element in an iterable to get a new iterable. The elements of the resulting iterable are filtered to it using the boolean-valued function. If the function returns false when called on an element, that particular element is left out of the result.
In Python, filtering can be done using the filter() function.
You will also see a glimpse of how to use the filter() function in this guide.
Reducing
Reducing or folding means reducing an iterable to a single cumulative value.
For example, you can reduce to calculate the sum of numbers in a list.
In Python, reducing is possible using the reduce() function.
Later in this guide, you are going to see examples of reducing as well.
Now that you have a basic-level understanding of functional programming, it is time to learn how to use the map() function.
The map() Function Syntax
The basic syntax of the map function is really simple:
map(function, iterable)
Where the function argument is a function that is called for each element in the iterable argument.
Furthermore, the function takes one argument, performs an operation on the argument, and returns the result.
The map() function returns a new iterable with the transformed values. It is a map object that can easily be converted to a list for example.
You can also pass multiple iterables to the map() function. In this case, the function needs to take the same number of arguments as there are iterables in the map() function call.
map(function, iterable1, iterable2, iterable3, ... , iterableN)
You are going to see an example of this as well, but first, we are going to deal with the map() function and a single iterable.
How Does the map() Function Work?
In the previous section, you learned the syntax of the map() function.
map(function, iterable)
But how does it actually work?
The first argument, function, is a transformation function. It transforms each element from one to another. The map() function calls this transformation function one by one for each element in the iterable.
Similar to how a for loop works, the map() function:
- Loops through the list of elements.
- Picks one element at a time.
- Calls the function on the element.
- Stores the result in a new iterable.
The function argument can be a regular function.
But it can also be a lambda function, method, class, a built-in function, and a user-defined function.
When you pass the function argument to the map() function, you should not call it! Instead, you should provide a reference to it. To do this, do not use parenthesis. Instead, give it the name of the function.
Okay, that is it for the theory.
To actually learn how to use the map() function, you need to see and play with some examples.
Let’s square a list of numbers with a regular for loop first.
numbers = [1, 2, 3, 4, 5] squared = [] for number in numbers: squared.append(number * number) print(squared)
Output:
[1, 4, 9, 16, 25]
Now, let’s use the map() function to do the same:
numbers = [1, 2, 3, 4, 5] def square(number): return number ** 2 squared = map(square, numbers) print(list(squared))
Output:
[1, 4, 9, 16, 25]
Let’s inspect the code to understand how it works:
- Line 1: You specify a list of numbers.
- Lines 3-4: You specify a function that takes a number, squares it, and returns a result.
- Line 5: Call the map() function on the list of numbers with the squaring function. The map() function takes the square function and calls it for each number.
- Line 7: You print the result list of squared numbers. The reason we use the list() function here is because the map() function returns a map object which we want to convert to a list.
Awesome, now you understand how the map() function works.
As we mentioned earlier, the map() function allows you to replace the for loops with a shorter expression.
But if you look at the above piece of code, you can see this is not the case. There is equally as much code as in the regular for loop approach.
To use the map() function more effectively, you can pass the function argument as a lambda function in some cases.
In the next section, you are going to learn how to do this.
Using map() with Lambda Functions
In Python, you commonly use the map() function with a lambda function instead of separately specifying the transformation function.
Using a lambda function is only possible if the mapping function consists of a single expression, which usually is the case.
Learn more about lambda functions in Python.
Here is a quick primer for those who don’t know what is a lambda.
Quick Primer: What Is a Lambda Function
In Python, a lambda function is an anonymous function. It can take any number of arguments but only contain a single expression.
A lambda function does not have a name, so it cannot be called afterward.
As an example, here is a lambda function that multiplies a number by 5:
lambda x : x * 5
This lambda function works exactly like this regular function:
def multiply(x): return x * 5
However, because a lambda has no name, it cannot be called afterward. Instead, the lambda function needs to be called right away.
For instance, let’s create a lambda function that multiplies a number by 5 and instantly calls it on a number:
(lambda x : x * 5)(15) # returns 75
But why would you ever do this?
The above example is indeed not useful. You could multiply a number by 5 using the * operator directly instead.
However, lambda functions are useful when the functionality is needed only once.
This is because you can write a lambda function instead of specifying a separate function and leaving it hanging in the codebase.
A perfect example of this is when using the map() function.
Lambda Function as an Argument in the map() Function
As stated earlier, the map() function takes a function argument that can also be a lambda function.
Let’s go back to the example of squaring numbers.
This time, let’s write the square() function as a lambda function directly into the map() function call:
numbers = [1, 2, 3, 4, 5] squared = map(lambda number: number ** 2, numbers) print(list(squared))
Output:
[1, 4, 9, 16, 25]
The map() function calls the lambda function on each number in the list. This squares the numbers one by one and returns a list of squared numbers.
Thus, this piece of code works exactly like the one with a separate square() function. But this time there is no separate square() function. Instead, the functionality is defined directly in the map() function call.
This is a perfect example of how to use a lambda function to make your code shorter and more concise.
In this example, you needed the squaring functionality once. Thus, it would make no sense to write a separate function and leave it hanging there. Instead, it is a lot cleaner to write the function as a lambda directly into the map() function.
However, you should keep in mind not every function can be written as a lambda function. This is because, by definition, a lambda can take an arbitrary number of arguments but only contain a single expression.
In other words, you can only write simple functions as lambdas.
Next, let’s talk about using the built-in functions with the map() function.
Using map() with Built-In Functions
At this point, it might not be a surprise you can also use a built-in function inside the map() function.
For example, let’s convert a list of strings to a list of integers.
In Python, you can convert an object to an integer using the built-in int() function.
Now, let’s do this to an entire list of strings using the map() function:
numbers = ["1", "2", "3", "4", "5"] squared = map(int, numbers) print(list(squared))
Output:
[1, 2, 3, 4, 5]
The map() function takes each string in the numbers list and calls the int function on it.
Modifying Strings with the map() Function
So far you have only dealt with lists when it comes to using the map() function.
However, the map() function can be called on any type of iterable in Python.
The following data types are examples of iterables in Python:
- String
- Dictionaries
- Sets
- Lists
- Tuples
Let’s see some examples of modifying strings with the map() function.
In Python, a string is an iterable collection of characters.
For example, let’s remove dashes from a string using the map() function. Notice that you can accomplish this task significantly easier by using the replace() method of a string. However, we are going to use the map() function for demonstration purposes.
Here is how it looks in code:
name = "H-e-l-l-o" def nodash(character): if character == "-": return "" else: return character parsedCharacters = map(nodash, name) parsedName = "".join(parsedCharacters) print(parsedName)
Output:
Hello
This piece of code:
- Specifies a function that checks if a character is a dash or not. If it’s a dash, an empty character is returned. If it’s not, the character itself is returned.
- Calls the map() function on a string by calling the nodash function for each character in a string.
- Gives a result that is a map object with non-dash characters.
- Converts the result to a string by joining the characters using an empty string separator.
Calling the map() Function on Multiple Iterables
So far you have seen how to apply the map() function on a single iterable, such as a list or string.
But you can also call the map() function on an arbitrary number of iterables.
In this case, the number of arguments to the mapping function should match the number of iterables.
To make sense of this, let’s see an example.
Here we have a list of first names and a list of second names. Our task is to combine the first names and the last names to form the full names.
Here is how it looks in code:
firstNames = ["Donald", "Henry", "Jon"] lastNames = ["Cerrone", "Cejudo", "Jones"] fullNames = map(lambda first, last: first + " " + last, firstNames, lastNames) print(list(fullNames))
Output:
['Donald Cerrone', 'Henry Cejudo', 'Jon Jones']
Let’s have a closer look at the lambda function used above:
lambda first, last: first + " " + last
- The map() function takes the first element from the firstNames list and uses it as the first argument.
- Then it takes the first element in the lastNames list and uses it as the second argument.
- The lambda function combines the firstName and the secondName and separates them by a space to form a full name.
Let’s see another example where we call the map() function on two iterables.
In this example, we have a list of numbers and powers. The task is to raise each number to the corresponding power in the other list.
Here is how it looks in code:
numbers = [2, 4, 6, 8] powers = [1, 2, 3, 4] powerNumbers = map(pow, numbers, powers) print(list(powerNumbers))
Output:
[2, 16, 216, 4096]
Here is an illustration of how the above code works:
Similar Functions to map(): filter() and reduce()
Earlier in this guide, you learned the concept of functional programming in a nutshell.
The key features of functional programming are the ability to use pure functions to:
- Map iterables.
- Filter iterables.
- Reduce (or fold) iterables.
So far in this guide, you have learned how to use the map() function.
In addition to this, it is good to know there are two similar functions:
- filter() for filtering iterables.
- reduce() for reducing iterables.
Let me show you a bunch of examples.
The filter() Function
Python has a built-in filter() function that represents functional programming.
The filter() function allows you to filter values in an iterable.
Similar to the map() function, the filter() function is a shorthand replacement for a for loop.
The filter() function takes a function and an iterable as an argument.
The function is sometimes called a predicate function. It acts as a filtering function that returns True or False for each element in the iterable.
The filter() function loops through the iterable and calls the filtering function for each element. If the function returns True, the element goes to the result. If it returns False, the element is filtered out of the list.
The result of the filter() function call is a filter object that consists of the filtered values.
For example, let’s filter even numbers in a list of integers:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] evenNumbers = filter(lambda number: number % 2 == 0, numbers) print(list(evenNumbers))
Output:
[2, 4, 6, 8, 10]
The filter() function checks if each number is divisible by 2. If the number is divisible by 2, it is even and makes it to the result. If the number is not divisible by 2, it is odd and is dropped.
As you can see, the filter() function call looks a lot like the map() function call. This is because both functions represent the functional programming paradigm and are implemented from the same standpoint.
Next, let’s take a look at the third functional programming function, that is, the reduce() function.
The reduce() Function
Similar to the map() and filter() functions, the reduce() function represents functional programming.
The idea of the reduce() function is to take an iterable and fold it into a single value.
For example, given a list of integers, you can calculate the sum of the list by reducing the numbers to a single cumulative value.
The reduce() function follows this procedure:
- Call a function on the first two elements of an iterable to get a partial result.
- Call the function again on the partial result and the third element of the iterable to update the partial result.
- Repeat this process as long as there are values in the iterable.
- Return the cumulative result.
To use the reduce() function, you need to import it from the functools module where it was moved recently.
For example, let’s calculate the sum of a list of numbers:
from functools import reduce numbers = [1, 2, 3, 4] sum = reduce(lambda x, y: x + y, numbers) print(sum)
Output:
10
Here is an illustration of the above code:
However, you should stay away from using the reduce() function!
There is always a better approach to solve the problem.
As a matter of fact, one reason to move the reduce() function into the functools module was to push developers away from using it.
Learn more about the reduce() function in Python.
Thus far you have learned how to use the map() function and the two functional programming functions filter() and reduce().
But because Python is not really a functional programming language, more often than not you should not use these functions.
There are better alternatives.
The map() Function Alternatives in Python
Now you have a basic understanding of how the map() function works. In addition, you know how similar functions reduce() and filter() work.
Next, let’s discuss the map() function alternatives.
As stated earlier, using the map() function is not the most Pythonic way to solve problems. It can make the code unreadable and harder to understand.
Furthermore, Python was not intended to be a functional programming language.
Thus, there are some better alternatives you can use to avoid using the map() function.
In Python, you can compress a regular for loop to a one-liner expression using what is called comprehension.
There are four types of comprehensions in Python:
- List comprehensions
- Dictionary comprehensions
- Set comprehension
- Generator comprehensions (officially known as generator expressions)
The comprehensions are quite similar to one another.
To keep it in scope, let’s take a look at list comprehensions as a replacement for the map() function.
Learn more about for loops and comprehensions.
List Comprehensions
In Python, you can compress a for loop into a one-liner expression using a list comprehension.
A regular for loop looks something like this:
for item in list: if condition: action(item)
A list comprehension version of this loop looks like this:
[action(item) for item in list if condition]
Where the if condition part is not mandatory if there is no condition to check against.
Here is an illustration of how to transform a regular for loop into a list comprehension.
Let’s see an example.
Earlier in this guide, you learned how to use the map() function to square a list of numbers.
Let’s do the same using a list comprehension:
numbers = [1, 2, 3, 4, 5] squared = [number ** 2 for number in numbers] print(squared)
Output:
[1, 4, 9, 16, 25]
This approach is much smoother and more concise than using the map() function.
numbers = [1, 2, 3, 4, 5] squared_nums = map(lambda x: x ** 2, numbers) print(list(squared_nums))
In this case, there are two things that stand out:
- The list comprehension version is more intuitive and readable. It reads almost like English.
- You do not need to convert the result to a list using the list() function with the list comprehension approach.
So instead of using the map() function to complete this task, you should consider doing it with a list comprehension instead.
Similar to regular for loops, list comprehensions work with any other iterable types in Python.
For example, you can use list comprehension on a string too.
For example, given a string of integers, let’s square each integer using a list comprehension:
numberString = "12345" numbersSquared = [int(character) ** 2 for character in numberString] print(numbersSquared)
Output:
[1, 4, 9, 16, 25]
As the last example, let me show you how to use list comprehension as a replacement for the filter() function.
For example, let’s filter even numbers in a list of numbers:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] evenNumbers = [number for number in numbers if number % 2 == 0] print(evenNumbers)
Output:
[2, 4, 6, 8, 10]
Awesome! Now you know the basics of mapping in Python, and what alternatives you have.
We could end this guide here, but there is one thing about the map() function we did not cover yet. This is the map object which is returned by the map() function.
Deep Dive: The map Object
In Python, the map() function returns a special map object.
Throughout this guide, you have seen examples where we use a map to transform an iterable into another.
In each example, you convert the result into a list using the list() function to display it.
But what if we did not convert the result to a list?
Let’s see an example by squaring a list of numbers and showing the result as-is.
numbers = [1, 2, 3, 4, 5] numbersSquared = map(lambda number: number ** 2, numbers) print(numbersSquared)
Output:
<map object at 0x7faa24068130>
The result is a map object.
Printing this map object does not display the squared numbers as a result.
But why is that?
It all boils down to performance.
A map object is an iterator object.
An iterator does not store a single value, which makes it highly efficient. An iterator has a state. It only cares about the current value and knows how to get the next one.
So at this point, the map object has not calculated the squared values yet. Instead, it does it on-demand when we try to access the values.
To actually calculate the squares, call the next() method of the iterator.
For example:
numbers = [1, 2, 3, 4, 5] numbersSquared = map(lambda number: number ** 2, numbers) print(next(numbersSquared)) print(next(numbersSquared)) print(next(numbersSquared)) print(next(numbersSquared)) print(next(numbersSquared))
Output:
1 4 9 16 25
Each time you call the next() function, the iterator grabs the next number and calculates its square.
By the way, an iterator is designed such that it can be looped through using the for loop syntax.
For example:
numbers = [1, 2, 3, 4, 5] numbersSquared = map(lambda number: number ** 2, numbers) for number in numbersSquared: print(number)
Behind the scenes, the for loop calls the next() method of the iterator in a similar way you did above.
Another example of on-demand computation is when converting the map object to a list. When you do this, the map iterator calculates the squared numbers and places them in a list.
At this point, I recommend reading this complete guide on iterators and iterables in Python.
Conclusion
Today you learned how to use the map() function in Python.
To recap, the map() function is an example of functional programming.
The map() function can be used to transform a collection of items into another. It is a shorthand replacement for a for loop.
For instance, you can convert a list of numbers to a list of numbers squared using the map() function.
The map() function calls a transformation function for each element in the iterable.
It is good to understand how the map() function works. However, most of the time you should use some alternative approach to transform iterables.