Even though Python is an object-oriented language, it still offers functions that provide a functional Programming style. One of these functions is the built-in map function, which can be a very useful function to know.
In this tutorial, we will learn what the map function is in Python and how to use it.
map function
Let’s say you want to create a list using a list that we already have. Meaning we want to use the list we have, apply some sort of operation or function to each element, and use those outputs to create a new list.
An example would be if we have a list of numbers and we wanted to create a new list that contains their squares. Well, one way to accomplish this would be to iterate over the list of numbers using a for loop and apply a function that returns the square of each number or element. And as we are iterating over the list, we can add or append the squared values to our new list.
Let’s see how we would do that in code:
We have a list of numbers, num_list, and we want to create a new list, num_list_squared, that contains the squares of num_list. We use a for loop to loop over num_list, and append the square of each number or num to our num_list_squared list.
Another way of accomplishing this would be to use the built-in Python function called map.
The map function takes in two arguments: the function we want to apply and the iterable object or sequence we want to apply it to (such as a list in this case). In other words, the map function maps or applies this function to each element of the sequence that we pass in.
map(function, iterable)
This map function will return a map object
, which is an iterator. If we want to create a list from this map object, we would need to pass in our map object to the built-in list function as follows:
list(map(function, iterable))
So if the iterable is a list of the elements x, y, and z, the map function accomplishes the following:
list(map(f, [x, y, z])) → [f(x), f(y), f(z)]
The function f, is the function that is passed to the map function as an argument.
Let’s see how we can accomplish the above code using the built-in map function:
Remember that we can apply the map function to each element in any iterable object or sequence, not just a list.
Let’s break down what happened in this line of code:
num_list_squared = list(map(squared, num_list))
The map function took the first element from num_list, which is a 1, and passed it in as an argument to the squared function (since we passed that function in as the first argument to the map function). The squared function then returned the square of 1, which is 1, and it was added to our map object. The map function then took the second element from num_list, which is 2, and passed it in as an argument to the squared function. The squared function returned the square of 2, which is 4, which was then added to our map object. After it finished going through the num_list elements and the rest of our squared numbers were added to the map object, the list function casts this map object onto a list, and that list was assigned to the variable num_list_squared.
using lambda expressions
We can shorten our code even further by instead passing in a lambda expression as our function:
For more information on lambda functions:
The functions that we pass in to map can also be built-in functions in Python. For example, if we have a list of strings and we want to create a new list that contains the lengths of these strings, we can just pass in the built-in len function as follows:
list(map(len, list_of_strings))
To learn more about iterables, iterators, and iteration:
cryptography: caesar cipher
Let’s try a slightly more interesting example involving cryptography, specifically the caesar cipher. The caesar cipher encrypts a message by taking each letter in the message, and replacing it with a shifted letter, or a letter that is a specified number of spaces away in the alphabet. So if we choose the number of spaces to be 1, then each letter will be replaced with the letter 1 space away in the alphabet. So the letter a will be replaced with the letter b, the letter b will be replaced with the letter c, and so on. If we choose the number of spaces to be 2, then a will be replaced with c, and b will be replaced with d.
If while we are counting spaces we get to the end of the alphabet, then we go back to the beginning of the alphabet. In other words, the letter z will be replaced with the letter a (if we shift 1 space), or with the letter b (if we shift 2 spaces).
For example, if the message we want to encrypt is ‘abc’ and we choose the number of spaces to be 1, then the encrypted message will be ‘bcd’. If the message is ‘xyz’, then the encrypted message will be ‘yza’.
using the map function
Well, we are applying something to each element of an iterable object. In this case, the iterable object is a string, and we would like to replace each letter/element in our string by a different one. And the map function can do exactly that!
Let’s assume that all messages will be lowercase letters only. And the number of spaces will be a number between 0–26. Remember, we only want to replace letters with other letters. Thus, any non-letter elements, such as a space or symbol, will be unchanged.
We first need access to the lowercase alphabet. We can either write out a string with all the lowercase letters, or we can use the string module as follows:
abc = 'abcdefghijklmnopqrstuvwxyz'
or
import string
abc = string.ascii_lowercase
print(abc)
# 'abcdefghijklmnopqrstuvwxyz'
Then, we can write our encrypt function as follows:
def encrypt(msg, n):
return ''.join(map(lambda x:abc[(abc.index(x)+n)%26] if x in abc else x, msg))
encrypt('how are you?',2)
# 'jqy ctg aqw?'
We create the function encrypt with two parameters: the message we want to encrypt, msg, and the number of spaces n we want to shift the letters by. The iterable we pass in to the map function is the message, msg. The function we pass in to the map function will be a lambda function, which takes each element from the msg string, and if the element is a letter in the alphabet, it replaces it with the shifted letter depending on the n value we pass in. It does so by taking the current index of that letter in the alphabet, or abc.index(x), adds the n value to it, and then takes the modulus of that sum. The modulus operator is used to start back at the beginning of the alphabet if we get to the end (if abc.index(x)+n is a number greater than 25). In other words, if the original letter was z (which will have the index 25 in the abc string we created above), and the n value is 2, then (abc.index(x)+n)%26 will end up being 27%26, and that will yield a remainder of 1. Thus replacing the letter z with the letter of the index 1 in the alphabet, which is b.
map(lambda x:abc[(abc.index(x)+n)%26] if x in abc else x, msg)
Remember that the map function will return a map object. Thus, we can use the string method join, which takes in an iterable (which the map object is, since it is an iterator, and all iterators are iterable), and then joins it into a string. The function then returns this string.
To decrypt a message, we can use the following decrypt function (notice how we are subtract n from abc.index(x) instead of adding it):
def decrypt(coded, n):
return ''.join(map(lambda x:abc[(abc.index(x)-n)%26] if x in abc else x, coded))
decrypt('jqy ctg aqw?',2)
# 'how are you?'
If you enjoy reading stories like these and want to support me as a writer, consider signing up to become a Medium member. It’s $5 a month, giving you unlimited access to stories on Medium. If you sign up using my link, I’ll earn a small commission.
I hope you enjoyed this tutorial on the map function in Python. Thank you for reading!