Python map() function (Transform Iterables)

The map() function in Python is a built-in function that is used to apply a function to each item in an iterable (array, list, tuple, dictionary, set) and returns an iterator.

This makes it very useful for transforming data of iterables.

 

 

The Syntax of Python map() Function

The syntax of the Python map() function is straightforward. It takes a function and one or more iterable objects and applies the function to each item in an iterable:

map(function, iterable, ...)

One of the key benefits of using the map() function is readability and efficiency. It allows you to perform operations on each item in an iterable without using an explicit for loop, which is faster when dealing with large amounts of data as you’ll see later in this tutorial.
Consider the following example:

def add_two(x):
    return x + 2
numbers = [1, 2, 3, 4, 5]
addition = map(add_two, numbers)
print(list(addition))

Output:

[3, 4, 5, 6, 7]

Here, we define a function add_two() which takes an integer as input and returns the integer plus 2. We then use this function with map(), which applies add_two() to each item in the numbers list.

The result is a new list where each element is the corresponding element in the original list incremented by two.

 

The Return Type of map()

When you use the Python map() function, it doesn’t immediately return a list of results. Instead, it returns an iterator.

This is an object that generates the results on-the-fly as you iterate over them, which is more memory-efficient than generating all results at once.
Here’s a simple example that demonstrates this:

def multiply_by_two(x):
    return x * 2
numbers = [1, 2, 3, 4, 5]
result = map(multiply_by_two, numbers)
print(result)
print(list(result))

Output:

<map object at 0x7f216e6f5970>
[2, 4, 6, 8, 10]

The first print statement prints the map object itself, which is an iterator. The second print statement converts the map object to a list, forcing all results to be generated.
You can use the returned iterator in a for loop, converted into a list or tuple, or consumed by functions that accept an iterable as input.

 

map() Function in Python 2 vs Python 3

While the overall concept and usage of the map() function remains the same, there is a key difference in its implementation between Python 2 and Python 3.
In Python 2, map() returns a list:

# Python 2
numbers = [1, 2, 3, 4, 5]
result = map(lambda x: x**2, numbers)
print(result)  # Output: [1, 4, 9, 16, 25]

In Python 3, map() returns an iterator:

# Python 3
numbers = [1, 2, 3, 4, 5]
result = map(lambda x: x**2, numbers)
print(result)  # Output: <map object at 0x10d238d30>
print(list(result))  # Output: [1, 4, 9, 16, 25]

This change makes map() more memory efficient in Python 3, as the entire list of results is not generated all at once, but rather one at a time as you iterate over the result.

 

Pass Multiple Iterables

In the examples above, we used the map() function with a single iterable. Actually, the map() function can also take multiple iterables as arguments.

When used with multiple iterables, the map function will apply its function to the items of the iterables in a parallel manner.

This means it applies the function to the first item of each iterable, then to the second item of each iterable, and so forth.

The number of arguments the function must take should correspond with the number of iterables.

def add_numbers(x, y):
    return x + y
numbers1 = [1, 2, 3, 4, 5]
numbers2 = [10, 20, 30, 40, 50]
result = map(add_numbers, numbers1, numbers2)
print(list(result))

Output:

[11, 22, 33, 44, 55]

In this example, we define a function add_numbers() that takes two arguments and returns their sum. We then use the map() function with this function and two lists of numbers.

The map() function applies add_numbers() to each pair of items in the lists (the first item from each list, the second item from each list, etc.) and returns an iterator. We convert this iterator to a list and print the resulting list of sums.

 

Use Lambda Functions

Lambda functions (lambda expressions), also known as anonymous functions, are small, unnamed functions defined with the lambda keyword.

Unlike custom functions we used above, you can use lambda functions inside the map() function to create a quick transformation.

Here’s how to use a lambda function with map():

numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, numbers)
print(list(squared))

Output:

[1, 4, 9, 16, 25]

Here, the lambda function takes an input x and returns x squared. We use this function with map() and a list of numbers, and map() applies the lambda function to each number in the list. The result is a new list of the squares of the numbers.

 

map() Function with Dictionaries

You can use the map() function with dictionaries as well. It’s important to note that when using a dictionary with map(), the function is applied to the dictionary’s keys by default.

Manipulating Keys

def make_upper(key):
    return key.upper()

fruit_colors = {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}
result = map(make_upper, fruit_colors)

print(list(result))

Output:

['APPLE', 'BANANA', 'GRAPE']

In this example, the make_upper() function is used to convert the dictionary keys to uppercase. We use the built-in map() function, which applies make_upper() to each key in the dictionary.

Manipulating Values

If you want to manipulate the values of the dictionary instead, you can use the dict.values() method:

def add_exclamation(value):
    return value + '!'
fruit_colors = {'apple': 'red', 'banana': 'yellow', 'grape': 'purple'}
result = map(add_exclamation, fruit_colors.values())
print(list(result))

Output:

['red!', 'yellow!', 'purple!']

Here, the add_exclamation() function adds an exclamation mark to each value in the dictionary. We pass these values to map(), which applies add_exclamation() to each one.

 

Speed Comparison

The map() function is often faster than a manual for loop because it is implemented in C and can take advantage of vectorized operations.

I performed a simple speed comparison using the timeit module. use a simple operation, doubling each number in a list or array.

I used the timeit module in Python to measure the time it takes to perform this operation using each method.

Here’s a plan for the experiment:

  1. I created a list of 1 million numbers.
  2. I measured the time it takes to double each number in the list using the following methods:
    • Python map function
    • List comprehension
    • For loop

I run each operation 10 times and take the average to get a more accurate measurement.

import timeit
size = 10**6
lst = list(range(size))

# Define the operation (doubling each number)
operation = lambda x: x * 2

# Define the number of runs for the benchmark
runs = 10

# Benchmark the map function
start = timeit.default_timer()
for _ in range(runs):
    result = list(map(operation, lst))
map_time = (timeit.default_timer() - start) / runs

# Benchmark list comprehension
start = timeit.default_timer()
for _ in range(runs):
    result = [operation(x) for x in lst]
list_comp_time = (timeit.default_timer() - start) / runs

# Benchmark for loop
start = timeit.default_timer()
for _ in range(runs):
    result = []
    for x in lst:
        result.append(operation(x))
for_loop_time = (timeit.default_timer() - start) / runs

print(map_time)
print(list_comp_time)
print(for_loop_time)

Output:

0.1796810700005153
0.18024229000147898
0.3354743200005032

As you can see, the map function is slightly faster than list comprehension, and both are significantly faster than a standard for loop.

 

Differences between map() and filter()

While the map() and filter() functions are similar in that they both take a function and an iterable as arguments, they serve different purposes.
The map() function applies a given function to each item of an iterable and returns a list of the results. On the other hand, the filter() function constructs a list from elements of an iterable for which a function returns true.
Here’s an example to illustrate the difference:

numbers = [1, 2, 3, 4, 5]

# Using map function to square the numbers
result_map = map(lambda x: x**2, numbers)
print(list(result_map))  # Output: [1, 4, 9, 16, 25]

# Using filter function to get only even numbers
result_filter = filter(lambda x: x % 2 == 0, numbers)
print(list(result_filter))  # Output: [2, 4]

In the example above, map() applies the lambda function to each element, so the length of the result is the same as the input list. filter(), however, applies the lambda function and only keeps those elements where the function returns True.

 

Real-World Problems to Solve Using map()

To further illustrate the power and versatility of the map() function, let’s look at how you can use it to solve real-world problems.
Data Transformation
Suppose you are working with a dataset of customer reviews, and you need to normalize the text by making it all lowercase and removing punctuation.

You could define a transformation function and then use map() to apply this function to each review in the dataset:

import string

# Define the transformation function
def normalize_text(text):
    text = text.lower()  # Convert to lowercase
    text = text.translate(str.maketrans('', '', string.punctuation))  # Remove punctuation
    return text
reviews = ["Great product!", "I love it.", "Best purchase I've made."]
normalized_reviews = map(normalize_text, reviews)
print(list(normalized_reviews))

Output:

['great product', 'i love it', 'best purchase ive made']
Leave a Reply

Your email address will not be published. Required fields are marked *