Функция map в Python

6123

Для грамотного использования любой функции или метода, рекомендуется сначала рассмотреть их внутреннюю реализацию: понять, какие аргументы они получают и какое значение возвращают. Функция map принимает два аргумента: iterable и function (итерируемый объект и функция) и применяет функцию к каждому элементу объекта. Возвращаемое значение — объект map. Он является итератором, который можно конвертировать в список или множество с помощью встроенных функций.

В этом материале разберем в подробностях аргументы и возвращаемое значение функции map.

Первый аргумент: функция

Первым аргументом функции map является функция. Думая о функциях в Python, в первую очередь в голову приходят те, что определяются с помощью ключевого слова def, но в map можно использовать в том числе встроенные и анонимные функции или даже методы.

Встроенные — это заранее созданные функции. Map — одна из них. Анонимные, называемые также лямбда-функциями, — это функции, которые определяются без имени с ключевым словом lambda. Разберем на примерах.

Обычные функции

Есть список чисел, которые нужно удвоить. Первый вариант — перебрать список с помощью цикла for. Второй — использовать генерацию списка. Но очевидно, что можно задействовать и функцию map.

elements = [1,2,3,4]
elements_by2 =[]

for element in elements:
    elements_by2.append(element*2)

#elements_by2 = [2,4,6,8]
elements = [1,2,3,4]
element_by2 = [ element*2 for element in elements]

#elements_by2 = [2,4,6,8]

В первую очередь функция определяется с помощью def. Она принимает в качестве аргумента число и возвращает это число, умноженное на два. Затем эта функция применяется к каждому элементу списка с помощью map. Поскольку функция map возвращает объект map, его нужно конвертировать в список с помощью встроенной функции list.

def multiply(x):
    return x*2

elements = [1,2,3,4]
elements_by2 = list(map(multiply,elements))

#elements_by2 = [2,4,6,8]

Можно сделать и что-нибудь посложнее, например, вернуть 0 на месте четных чисел, а нечетные вывести как есть.

def even_odd(x):
    if x%2==0:
        return 0
    else:
	return x

elements = [1,2,3,4]
elements_new = list(map(even_odd,elements))

#elements_new = [1,0,3,0]

Идея должна быть ясна — применение одной функции к каждому элементу итерируемого объекта.

Анонимные функции

Вместе с функцией map можно использовать и анонимные функции. Это довольно частый сценарий.

У анонимных функциях следующий синтаксис:

lambda аргументы: выражение

Эти функции нужны для краткосрочного использования. Они могут иметь любое количество аргументов, а возвращаемое значение определяется выражением. Их можно найти не только в Python, но и в других языках программирования.

Рассмотрим предыдущую проблему с помощью анонимной функции. Есть список элементов и необходимость их удвоить. В таком случае у лямбда-функции есть один аргумент (x), который возвращает значение, умноженное на 2 (x*2).

elements = [1,2,3,4]
elements_by2 = map(lambda x: x*2, elements)

#elements_by2 =[2,4,6,8]

Также функцию map можно использовать и с методами. Методы похожи на функции, но есть некоторые отличия. В частности, методы связаны с ассоциированными с ними объектами.

Есть список городов, в названиях которых нужно сделать первую букву заглавной. Этого можно добиться с помощью комбинации из функции map и метода title.

cities = ['madrid', 'munich', 'valencia']
cities_cap = list(map(lambda x:x.title(),cities))

#cities_cap = ['Madrid', 'Munich', 'Valencia']

Встроенные функции

В стандартной библиотеке Python много доступных функций, которые можно использовать в map. Все они перечислены в документации Python.

elements = [1,2,3,4]
elements_str = list(map(str,elements))

#elements_str = ['1','2','3','4']

Предположим, есть список чисел, каждый из элементов которого нужно превратить в строку. Это запросто можно сделать с помощью функции map и встроенной функции str.

Второй аргумент: итерируемый объект

Самый распространенный итерируемый объект — списки, но бывают и объекты других типов. Итерируемый объект — это объект с определенным количеством значений, которые можно перебрать, например, с помощью цикла for. Множества, кортежи, словари также являются итерируемыми объектами и их можно использовать в качестве аргументов для функции map. Вот некоторые примеры.

Есть кортеж из чисел, каждое их значение в котором нужно увеличить на единицу. Это запросто делается с помощью функции map. Также потребуется использовать встроенную функцию tuple(), чтобы превратить возвращаемый объект map в кортеж.

elements = (1,2,3,4)
elements_plus1 = tuple(map(lambda x:x+1,elements))

#elements_plus1 = (2,3,4,5)

Есть множество чисел, и для каждого нужно получить куб. Множество будет вторым аргументом функции map. Чтобы превратить результат в множество, потребуется использовать встроенную функцию set().

def cube(x):
    return x**3

elements = {1,2,3,4}
elements_cube = set(map(cube,elements))

#elements_cube = {8,1,27,64}

elements2 = {1,2,3,4}
elements2_cube = set(map(lambda x:x**3,elements))

#elements2_cube = {8,1,27,64}

Итерируемый объект может быть и словарем.

elements = {'hidrogen':1, 'helium':2, 'carbon':6}
elements_upper = list(map(lambda x:x.title(),elements))

#elements_upper = ['Hidrogen','Helium','Carbon']

Или списком кортежей. Можно создать новый список, который будет содержать только каждый третий элемент каждого кортежа. Или даже изменить каждый третий элемент.

students = [('Amanda','161cm','51kg'), ('Patricia','165cm','61kg'), ('Marcos','191cm', '101kg')]
students_height = list(map(lambda x:x[1], students))

#список со строками
#students_height = ['161cm','165cm','191cm']

students_weight = list(map(lambda x:int(x[2][:-2]), students))

#список с цислами
#students_weight = [51, 61, 101]

В последнем примере итерируемым объектом будет функция range. Предположим, что нужно создать список строк от 0 до 20. Это можно добиться с помощью функции range в качестве итерируемого объекта для функции map.

list_num = list(range(0,21)) 
#list_num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

list_str = list(map(str,range(0,21))) 
#list_str = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']

Теперь перейдем к третьему аспекту — возвращаемому значению.

Возвращаемое значение: итератор

Функция map возвращает объект map, который является итератором. Его можно превратить в список, множество или кортеж с помощью встроенной функции.

elements = [1,2,3,4]

elements_by2 = map(lambda x:x*2,elements)
print(type(elements_by2))
#<class 'map'>

elements_list = list(map(lambda x:x*2,elements))
print(type(elements_list))
#<class 'list'>

elements_set = set(map(lambda x:x*2,elements))
print(type(elements_set))
#<class 'set'>

elements_tuple = tuple(map(lambda x:x*2,elements))
print(type(elements_tuple))
#<class 'tuple'>

Резюме

  1. Функция map принимает два аргумента:
    (1) функцию
    (2) итерируемый объект.
  2. Применяет функцию к каждому элементу итерируемого объекта и возвращает объект map.
  3. Функция может быть (1) обычной, (2) анонимной или (3) встроенной.
  4. Списки, множества, кортежи и другие итерируемые объекты могут выступать в качестве второго аргумента функции map.
  5. Объект map можно запросто конвертировать в другой итерируемый объект с помощью встроенных функций.

Учитесь программировать по книгам, подписывайте на телеграм каналы:

Книги Python разработчика RU / EN

Книги / Data Science / RU-EN

Тест на знание python

Какой будет результат выполнения кода — print(abc) ?
Что выведет этот код?
Какой будет результат выполнения этого кода?
Что выведет этот код?
Какой ввод НЕ приведет к ошибке?
Александр
Я создал этот блог в 2018 году, чтобы распространять полезные учебные материалы, документации и уроки на русском. На сайте опубликовано множество статей по основам python и библиотекам, уроков для начинающих и примеров написания программ. Пишу на популярные темы: веб-разработка, работа с базами данных, data sciense и другие...