Python Simplified

Understanding Python map function

Python map function

Introduction

Do you need to apply the same transformation/function repeatedly over a collection of items such as list or tuple or set, etc.? One obvious way to do this is to iterate over all the elements using an explicit for loop and apply the transformation. For example, given a list mylist = [1, 2, 3, 4, 5], you can square each element using for loop as below:

				
					>>> mylist = [1, 2 3, 4, 5]
>>> squares = []
>>> for item in mylist:
...     squares.append(item**2)
				
			

This doesn’t look Pythonic and is not efficient. Python provides a built-in  map function that is much more efficient than for loop. The map function takes a function and one or more iterables and applies the same function to all the elements and returns the result. The final result must be converted to list or tuple or set, etc. 

In this article, we will go through the map function in detail. We will cover zip and filter functions in the next article.

Throughout this article, we will be using the terms iterable and iterator. Hence you must be familiar with both. The below definitions are sufficient for you to continue reading the article. However, we suggest you go through our detailed blog on iterables and iterators here

Iterables are objects that can be iterated over and are capable of returning one item at a time. For example, lists, tuples, sets, dictionaries, strings, range, etc. are iterables. Iterables must be converted to an iterator in order to access each element.

Iterators are the objects that are used to iterate over each element. When you pass iterable to __iter__ method, it returns the iterator object, and then using __next__ method you can iterate over all the elements.

map

The map function takes a function and one or more iterables (such as list, tuple, set, dictionary, range, etc.) as arguments and returns an iterator object after applying the function to each item in the iterable(s).

Syntax

				
					map(function, *iterables)
				
			

function — function that takes as many arguments as there are iterables. 
iterables — one or more iterables like list, tuple, set, etc.

how map function works

The output of the map function is an iterator. In order to access the elements in an iterator you need to loop through the iterator using for loop or you can pass the output to list, tuple, or set, etc. In the below examples, we will be passing the output of the map to the list. 

Let’s see some examples. The map vs. list comprehension is a very common question. Hence, in the below examples, we will also mention the code for list comprehension as an alternative to the map function. At the end of the article, we will make a distinction between map vs. list comprehension.

Example 1:

Given a list of numbers, can you return the cube of each number? 

				
					>>> mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
				
			

Using function: As you can see, the map function takes cube function and mylist as arguments. For each element in mylist, the cube function is applied and returns the result.

				
					>>> def cube(x):
...    return x**3

>>> map(cube, mylist)
<map at 0x2263e364b50>

>>> list(map(cube, mylist))
[1, 8, 27, 64, 125]
				
			

Using lambda function & list comprehension: We can also achieve this using the lambda function and list comprehension as shown below. 

				
					# Using lambda function
>>> list(map(lambda x: x**3, mylist))
[1, 8, 27, 64, 125]

# Using list comprehension
>>> [ x**3 for x in mylist]
[1, 8, 27, 64, 125]
				
			

Example 2

In example 1, we used only one iterable to map function. Let’s see how the map function works when there are multiple iterables of the same length. In the below examples we have two lists total and discount and we are calculating the discount amount by multiplying each element from the iterables.

				
					total = [120, 250, 550, 730, 999]
discount = [0.02, 0.05, 0.08, 0.15]
				
			

Using function: In this example, the calculate_savings function is applied to each element in both the iterables. Note that both iterables (total and discount) are of the same length. You’ll see what happens when iterables are of different lengths in the next example.

				
					>>> def calculate_savings(x, y):
...    return x * y

>>> list(map(calculate_savings, list1, list2))
[2.4, 12.5, 44.0, 109.5]
				
			

Using lambda function & list comprehension: You can also get the same results using the lambda function.

				
					# Using lambda function
>>> list(map(lambda x, y: x*y, total, discount))
[2.4, 12.5, 44.0, 109.5]

# Using list comprehension
>>> [x*y for x, y in zip(total, discount)]
[2.4, 12.5, 44.0, 109.5]
				
			

Example 3

If multiple iterables of different lengths are passed to the map function then the map function stops after finishing the shortest iterable. In the below example, list1 is the shortest iterable. So, the map function stops after processing all elements in list1

				
					>>> list1 = [1, 2, 3]
>>> list2 = [11, 22, 33, 44, 55]
				
			

Using function: As you can see, you only get 3 elements in the result as the map stops after processing all the elements in the shortest iterable i.e. list1 that has only three elements.

				
					>>> def my_func(a, b):
...    return a * b

>>> list(map(my_func, list1, list2))
[11, 44, 99]
				
			

Using lambda function & list comprehension: You can also get the same results using the lambda function.

				
					# Using lambda function
>>> list(map(lambda a, b: a*b,  list1, list2))
[11, 44, 99]

# Using list comprehension
>>> [x*y for x, y in zip(list1, list2)]
[11, 44, 99]
				
			

So far, we have seen examples of map functions using user-defined functions, lambda functions, and list comprehension. However, you can use any callable as the first parameter to the map function. The built-in functions, classes, methods, lambda functions, etc. are all callables. Let’s see few examples.

Any object that can be called using ( ) is called a callable. Using Python’s built-in function callable() you can check if the given object is callable or not. You can read our blog on callable to understand more.

Example 4

The below examples show that you can use any callable as the first parameter. The str.upper convert each item in the iterable to upper case, str.capitalize capitalizes each element, and len calculates the length of each element in the iterable, math.factorial calculate the factorial, float converts each element to float type, etc.

				
					>>> mylist = ['i', 'love', 'python', 'simplified']

# Example using string method upper()
>>> list(map(str.upper, mylist))
['I', 'LOVE', 'PYTHON', 'SIMPLIFIED']

# Example using string method capitalize()
>>> list(map(str.capitalize, mylist))
['I', 'Love', 'Python', 'Simplified']

# Example using built-in function len()
>>> list(map(len, mylist))
[1, 4, 6, 10]

# Example using math.factorial
>>> list(map(math.factorial, [1,2,3,4,5]))
[1, 2, 6, 24, 120]

# Example using float class
>>> mylist = ['1.1', '2.2', '3.3', '4.4', '5.5']
>>> list(map(float, mylist))
[1.1, 2.2, 3.3, 4.4, 5.5]
				
			

Advantages of the map function

As you saw in the examples above, there are more Pythonic alternatives to map function such as — explicit for loop, list comprehensions, and generator expressions. So, why should you consider using the map function? Here are the main 2 reasons –

  • map function is highly optimized and is far more efficient than the explicit for loop. So you should consider using the map function instead of for loop.
  • map function is memory efficient. Since the output of the map function is an iterator, you can access each element on-demand whereas in list comprehension you will have to load all elements into memory.

Map vs List comprehension

Map and list comprehension have their own pros and cons. Based on the speed comparison between map and list comprehension (refer to sample speed comparison below), the map function is marginally faster in most cases.

Speed Comparison

For speed comparison, we are repeating the operation of squaring each integer in the range 0–100 around 100,000 times. Below the are results. 

Case 1: map function with a function — 6.70 seconds
Case 2: list comprehension with function — 8.48 seconds
Case 3: list comprehension without function—6.81 seconds

As seen from the results, the map function runs faster than list comprehension (with and without function). But there is no clear winner.

So, which one you should consider using — map or list comprehension? If we need to load the entire data into the memory and/or if there is a need to iterate over the result multiple times then we should consider list comprehension. Otherwise, you can consider using the map function. Also, list comprehensions are more Pythonic than map functions.

				
					>>> from timeit import timeit
 
>>> def my_func(x):
...     return x ** 2
 
>>> print("map        :", timeit("list(map(my_func, range(100)))", globals=globals(), number=100_000))
map:       : 6.703942600000005

>>> print("listcomp 1 :", timeit("[my_func(x) for x in range(100)]", globals=globals(), number=100_000))
listcomp 1 : 8.489594000000011

>>> print("listcomp 2 :", timeit("[x**2 for x in range(100)]", globals=globals(), number=100_000))
listcomp 2 : 6.816997799999996
				
			

Summary

  • The map function takes a function and arbitrary number of iterables. Then function is applied to each element in the iterable(s).
  • The output of the map function is an iterator. So, you should use list, tuple, set, or for loop to iterate through all the elements.
  • If more than one iterables are passed to map function, then the map function stops after going through all the elements in the shortest iterable.
  • The first parameter to map need not be Python function. In fact, you can pass any callable can be passed as a function.
  • The main advantage of map function over for loop is that its highly optimized.
  • List comprehension can also be used in place of map function. But map function is more memory efficient. 
  • Map function is runs marginally faster than list comprehension. But not a clear winner. 
Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp
Share on email
Chetan Ambi

Chetan Ambi

A Software Engineer & Team Lead with over 10+ years of IT experience, a Technical Blogger with a passion for cutting edge technology. Currently working in the field of Python, Machine Learning & Data Science. Chetan Ambi holds a Bachelor of Engineering Degree in Computer Science.
Scroll to Top