Для грамотного использования любой функции или метода, рекомендуется сначала рассмотреть их внутреннюю реализацию: понять, какие аргументы они получают и какое значение возвращают. Функция 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'>
Резюме
- Функция map принимает два аргумента:
(1) функцию
(2) итерируемый объект. - Применяет функцию к каждому элементу итерируемого объекта и возвращает объект map.
- Функция может быть (1) обычной, (2) анонимной или (3) встроенной.
- Списки, множества, кортежи и другие итерируемые объекты могут выступать в качестве второго аргумента функции map.
- Объект map можно запросто конвертировать в другой итерируемый объект с помощью встроенных функций.