Mapping is a method that allows developers to process and transforms the elements in an iterable without explicitly declaring a for loop. And this is where the map() function comes in. It allows developers to transform every item of an iterable into a new iterable.
The map() function is one of the two built-in Python methods that support the functional programming style.
In this post, we discuss the working of the map() function, how to use the function to transform various iterables, and how to combine the function with other Python tools to perform more complex transformations.
Bear in mind that this post assumes an understanding of how for loops, functions, and iterables work.
What is the map() Function?
Python programmers sometimes come across problems where they need to do the same operation on all the elements of an iterable and make a new iterable out of it.
Typically, developers resort to using the for loop for this purpose, but using the map() function helps achieve the same result.
Much like the for loop, the map()function also iterates through the elements of the supplied iterable(s). It then outputs an iterator in which the transformation function has been applied to every element of the supplied iterable(s). It has the following signature:
map(function, iterable[, iterable1, iterable2,..., iterableN])
To break this down:
The function is applied to every element of the iterable, after which a new iterator is created, yielding the transformed items on demand. The function can be any method that accepts the same number of arguments as the number of iterables passed to the map() function.
It's important to note that the first argument in the signature is a function object. In other words, it requires you to pass a function without calling it. The first argument in question is the transformation function, responsible for transforming the original elements into the transformed elements.
The argument may be any kind of Python function and not just a built-in function, including classes, user-defined functions, and lambda functions.
Now, let's understand the map() function with an example. Suppose you need a program that accepts a list of numeric values as input and outputs a list with the square values of every number in the original list.
If you decide to use a for loop for this, the solution will look something like this:
numberList = [3, 6, 9] squareList =  for num in numberList: squareList.append(num ** 2) squareList # Output: [9, 36, 81]
The for loop in the code above goes through all the numbers in numberList and applies the exponent operation on every value. The results are stored in the squareList list.
However, if you use the map() function to develop a solution, the implementation would look like this:
def square(number): return number ** 2 numberList = [3, 6, 9] squareList = map(square, numberList) list(squareList) # Output: [9, 36, 81]
In the code above, square() is the transformation function and it "maps" every number in the list to its respective square value. Calling the map() function applies the defined square() function to the values in numberList. The result is an iterator holding the squared values.
Then, the list() function is called on map(), creating a list object which holds the squared values.
The map() function uses the C language, making it more efficient than a for loop in Python. But besides the efficiency, there is another advantage of using the function – lower memory consumption.
A Python for loop stores the entire list in the system memory, but this is not the case with the map() function. The map() function serves the list elements on demand and only stores one element in the system memory at a time.
Note: The map() function returns a list in Python 2.x, but in Python 3.x, it returns a map object. The map object serves as the iterator returning the list elements on demand. For this reason, you need to use the list() method to make the list object.
You can also use the map() function to convert all the elements of a list from strings to integers with the help of the int() function. Here's how you could approach this:
stringNumbers = ["32", "58", "93”] integers = map(int, stringNumbers) list(integers) # Output: [32, 58, 93]
In the above example, the map() function applies the int() method to every item in the stringNumbers list. The idea behind calling the list() function is that it will exhaust the iterator that the map() function returns.
The list() function then turns the iterator into a list object. Bear in mind that the original sequence is not modified in this process.
How map() Works with Different Functions
As mentioned earlier, map() works with all kinds of Python callables, given that the callable accepts an argument and can return a useful value. For instance, you could use the classes and instances that implement the __call__() method and also class, static, and instance methods.
Here is an example for you to consider:
numberList= [-2, -1, 0, 1, 2] #Making the negative values positive absoluteValues = list(map(abs, numberList)) list(map(float, numberList)) # It prints [-2.0, -1.0, 0.0, 1.0, 2.0] words = ["map", "with", "different", "functions"] list(map(len, words)) # It prints [3,4,9, 9]
One of the more common trends involving the map() function is the use of the lambda function as the primary argument. The lambda functions are especially useful when a developer needs to provide an expression-based function to map().
Let's take a step back and reimplement the square-value example discussed earlier with a lambda function. Here's how that would work:
numberList = [5, 10] squareList = map(lambda num: num ** 2, numberList) list(squareList) #Output: [25,100]
With the above example, it is clear that lambda functions are some of the most useful functions to couple with map()and are often used as the first argument to the map() function to swiftly process and transform iterables.
Using map() to Process Multiple Input Iterables
The transformation function will require as many arguments as the iterables passes if you provide several iterables to map(). Every iteration of the function will pass a value from every iterable as an argument to function. When the end of the shortest iterable is reached, the iteration stops.
For instance, consider the following use of map() with the pow() function:
listOne = [2, 4, 6] listTwo = [1, 2, 3, 7] >>> list(map(pow, listOne, listTwo)) # Output: [2, 16, 216]
If you're familiar with the pow() function, you will know that it accepts two arguments – let us call them a and b – and returns a to the power of b.
In the example above, the value of a is 2, and b is 1 in the first iteration. Coming to the second iteration, the a value is 4, b is 2, and so on. Observing the output, you will see that the output iterable is as long as the shortest iterable, which is listOne in this case.
Using this technique enables you to merge iterables holding numeric values using a variety of math operations.
Using map() to Transform Iterables of Strings
If some of your solutions involve working with iterables holding string objects, you may need to transform the objects using some sort of transformation function. The map() function can come in handy in these situations.
In this section, we discuss two different scenarios in which map() can be invaluable to transform iterables of string objects.
Using the str Class's Methods
When developers need to manipulate strings, they typically use the methods under the built-in str class. The methods help transform strings into new strings. If you're working with iterables containing strings and want to transform all the strings in the same manner, here's how you can use the map() function:
stringList = ["this", "is", "a", "string"] list(map(str.capitalize, stringList)) list(map(str.upper, stringList)) list(map(str.lower, stringList)) # Output: # [‘This', 'Is, A', 'String'] # ['THIS, 'IS', 'A', 'STRING'] # ['this', ‘is', a', 'string']
You can perform various transformations on every element in the stringList list using the str and map() methods. In most cases, developers find helpful methods that do not accept any additional arguments. These methods include the ones in the code above and some other methods such as str.swapcase() and str.title().
Sometimes, developers also use methods that accept additional parameters, such as the str.strip() function, which accepts a char argument that removes the whitespace. Here's an example of how you can use this method:
spacedList = ["These ", " strings", "have ", " whitespaces "] list(map(str.strip, spacedList)) #Output: ['These', 'strings', 'have', 'whitespaces']
As illustrated in the code above, the str.strip() method uses the default char value, with the map() method removing the whitespaces from the elements in spacedList.
However, if you need to supply arguments to the method and do not want to rely on the default value, using the lambda function is the right way to go.
Let's take a look at another example that uses the str.strip() method to remove ellipsis rather than whitespaces from the elements in a list:
dotList = ["These..", "...strings", "have....", "..dots.."] list(map(lambda s: s.strip("."), dotList)) # Output: ['These', 'strings', 'have', 'dots']
Here, the lambda function calls .strip() on the "s" object, removing both the dots preceding and trailing dots from the strings.
This approach to working with strings comes in handy when developers need to process text files that have trailing spaces or other unwanted characters that need to be removed from the text.
In such cases, developers can also use the str.strip() method without a custom char parameter – it removes the newline character from the text.
Removing Punctuation from Strings
Text processing problems come in all shapes and forms, and in some cases, unwanted punctuation marks remain in the document when the text is split into words.
An easy way to solve this problem is to create a custom function that removes these punctuations from an individual word via a regular expression holding the common punctuation marks.
Implementing this function is possible with the sub() method – a regular expression function present under the Python standard library's "re" module. Here's an example solution:
import re def punctationRemove(word): return re.sub(r'[!?.:;,"()-]', "", word) punctationRemove("...Python!") # Output: 'Python'
The punctationRemove() function has a regular expression pattern holding the common punctuation marks present in the English language. Notice how the apostrophe (') is not in the regular expression since it makes sense to keep contractions such as "I'll" as they are.
The re.sub() function in the code removes the punctuations by replacing a matched punctuation with an empty string. Finally, it returns a clean version of the word.
But this transformation function is only half of the solution – you now need to use the map() function to apply this function to all the words in a text file. One way to approach it is to feed the string to a variable, say "text," and then store the return value of the text.split() function in the words variable.
If you print the words variable, you will find that it is a list holding the words in the string as separate string items. You may be able to deduce the final step at this point – running the map function and passing the punctuationRemove function and words list to it.
Remember to put the entirety of this map function within a list() function to print out the list of words with punctuations removed.
The words you provide to the program may have punctuation marks on them. The call to the map() function applies the punctuationRemove() function to every word, removing all the punctuation marks. Therefore, the second list has all the cleaned words.
Transforming Number Iterables With map()
The map() method has a high potential of coming in handy when processing iterables that hold numeric values. With it, developers can perform a wide range of arithmetic and math operations, including converting strings to integers or floating numbers, among others.
Using the power operator is one of the most common math operations used to transform iterables holding numeric values. Here's an example of a program with a transformation function that accepts a number and returns the squared and cubed numbers:
def exponent(x): return x ** 2, x ** 3 numList = [3, 4, 5, 6] list(map(exponent, numList)) # Output: [(9, 27), (16, 64), (25, 125), (36, 216)]
The exponent() function accepts a number from the user and returns the square and cube values. Notice that the output includes tuples because Python handles the return values as tuples. Every call to the function returns a tuple of two.
Next, when the exponent() function is passed to the map() method as a parameter, it returns a list of tuples holding the processed numbers.
This is just one example of the math transformations possible with the map() method. The other tasks you can complete with map() include adding and subtracting specific constants from every element of the iterable. But you can also use functions such as sin() and sqrt() that are a part of the Python standard library's math module with map().
Here's an example of how you can use the factorial() method with map():
import math numbersList = [1, 2, 3, 4] list(map(math.factorial, numbersList)) # Output: [1, 2, 6, 24]
In this example, the numbersList list is converted into a new list holding the factorial values of the numbers in the original list. There are no limits to how you can use the map() function in your code. Make sure you give the function some thought and come up with your own programs to fortify your understanding of it.
If you find this article helpful, you may want to check out this article about FastAPI.