Использование функции map в Python

Введение

Встроенная в Python функция map() используется для применения функции к каждому элементу итерируемого объекта (например, списка или словаря) и возврата нового итератора для получения результатов. Функция map() возвращает объект map (итератор), который мы можем использовать в других частях нашей программы. Также мы можем передать объект map в функцию list() или другой тип последовательности для создания итерируемого объекта.

Функция map() имеет следующий синтаксис:

map(function, iterable, [iterable 2, iterable 3, ...]) 

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

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

Использование функции Lambda

Первый аргумент map() — это функция, которую мы используем для применения к каждому элементу. Python вызывает функцию один раз для каждого элемента итериируемого объекта, который мы передаем в map(), и возвращает измененный элемент в объект map. В качестве первого аргумента функции мы можем передать определенную пользователем функцию или использовать функции lambda, особенно если выражение будет менее сложным.

Синтаксис map() с функцией lambda выглядит следующим образом:

map(lambda item: item[] expression, iterable) 

С таким списком мы можем реализовать функцию lambda с выражением, которое хотим применить к каждому элементу в нашем списке:

numbers = [10, 15, 21, 33, 42, 55] 

Чтобы применить выражение к каждому из наших чисел, мы можем использовать map() и lambda:

mapped_numbers = list(map(lambda x: x * 2 + 3, numbers)) 

Здесь мы декларируем элемент в нашем списке как x. Затем мы добавим наше выражение. Мы передадим список чисел как итерируемый объект для map().

Для немедленного получения результатов мы распечатаем список объекта map:

print(mapped_numbers) 
Output[23, 33, 45, 69, 87, 113] 

Мы использовали list(), чтобы объект map был выведен как список, а не в трудной для интерпретации объектной форме, например: <map object at 0x7fc250003a58>. Объект map является итератором наших результатов, чтобы мы могли использовать его в цикле for или использовать list() для превращения в список. Мы делаем это здесь, потому что это хороший способ просмотра результатов.

В итоге map() наиболее полезна для работы с большими наборами данных, чтобы мы могли работать с объектом map, и не использовали для них конструктор, например, list().

Для небольших наборов данных список может быть более понятным, однако для этого обучающего модуля мы используем небольшой набор данных для демонстрации возможностей map().

Реализация определяемой пользователем функции

Аналогично lambda мы можем использовать определенную функцию для применения к итерируемому объекту. Функции lambda более полезны при использовании выражения с одной строкой, определяемые пользователем функции лучше подходят для более сложных выражений. Если же нам нужно передать в функцию другой элемент данных, применяемый к итерируемому объекту, определяемые пользователем функции будут удобнее для чтения.

Например, в следующем итерируемом объекте каждый элемент является словарем, содержащим различные детали о каждом из существ в нашем аквариуме:

aquarium_creatures = [     {"name": "sammy", "species": "shark", "tank number": 11, "type": "fish"},     {"name": "ashley", "species": "crab", "tank number": 25, "type": "shellfish"},     {"name": "jo", "species": "guppy", "tank number": 18, "type": "fish"},     {"name": "jackie", "species": "lobster", "tank number": 21, "type": "shellfish"},     {"name": "charlie", "species": "clownfish", "tank number": 12, "type": "fish"},     {"name": "olly", "species": "green turtle", "tank number": 34, "type": "turtle"} ] 

Мы решили, что все существа в аквариуме будут перемещены в один и тот же резервуар. Нам нужно обновить наши записи, чтобы показать, что все наши существа перемещаются в резервуар 42. Чтобы дать map() доступ к каждому словарю и каждой паре ключ:значение в словарях, мы построим вложенную функцию:

def assign_to_tank(aquarium_creatures, new_tank_number):     def apply(x):         x["tank number"] = new_tank_number         return x     return map(apply, aquarium_creatures) 

Мы определяем функцию assign_to_tank(), которая принимает aquarium_creatures и new_tank_number в качестве параметров. В assign_to_tank() мы передаем apply() как функцию в map() в последней строке. Функция assign_to_tank возвратит iterator, полученный от map().

apply() принимает в качестве аргумента x, что означает элемент в нашем списке — одиночный словарь.

Далее мы указываем, что x — это ключ "tank number" из aquarium_creatures, и что он должен хранить переданное значение new_tank_number. Мы возвратим каждый элемент после применения нового номера резервуара.

Мы вызовем assign_to_tank() с нашим списком словарей и новый номер резервуара, который нам нужно заменить для каждого существа:

assigned_tanks = assign_to_tank(aquarium_creatures, 42) 

После выполнения функции мы сохраним объект фильтра в переменной assigned_tanks, которую мы превратим в список и распечатаем:

print(list(assigned_tanks)) 

Вывод программы будет выглядеть следующим образом:

Output[{'name': 'sammy', 'species': 'shark', 'tank number': 42, 'type': 'fish'}, {'name': 'ashley', 'species': 'crab', 'tank number': 42, 'type': 'shellfish'}, {'name': 'jo', 'species': 'guppy', 'tank number': 42, 'type': 'fish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': 42, 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': 42, 'type': 'fish'}, {'name': 'olly', 'species': 'green turtle', 'tank number': 42, 'type': 'turtle'}] 

Мы присвоили новый номер резервуара нашему списку словарей. Используя функцию, которую мы определяем, мы включаем map() для эффективного применения функции к каждому элементу списка.

Использование встроенной функции с несколькими итерируемыми объектами

Помимо функций lambda и определяемых нами функций, мы можем использовать вместе с map() встроенные функции Python. Для применения функции с несколькими итерируемыми объектами мы передаем имя другого итерируемого объекта после первого. Рассмотрим в качестве примера функцию pow(), которая принимает два числа и возводит базовое число в указанную степень.

Здесь у нас списки целых чисел, которые мы хотим использовать с pow():

base_numbers = [2, 4, 6, 8, 10] powers = [1, 2, 3, 4, 5] 

Затем мы передадим pow() в качестве функции в map() и укажем два списка в качестве итерируемых объектов:

numbers_powers = list(map(pow, base_numbers, powers))  print(numbers_powers) 

map() применит функцию pow() к тому же элементу в каждом списке для возведения в степень. Поэтому в результатах мы увидим 2**1, 4**2, 6**3 и т. д.:

Output[2, 16, 216, 4096, 100000] 

Если мы передадим map() итерируемый объект, который будет длиннее другого итерируемого объекта, map() остановит расчеты после достижения конца наиболее короткого объекта. В следующей программе мы дополним base_numbers тремя дополнительными числами:

base_numbers = [2, 4, 6, 8, 10, 12, 14, 16] powers = [1, 2, 3, 4, 5]  numbers_powers = list(map(pow, base_numbers, powers))  print(numbers_powers) 

В расчетах программы ничего не изменится, и результат будет точно таким же:

Output[2, 16, 216, 4096, 100000] 

Мы использовали функцию map() со встроенной функцией Python и посмотрели на одновременную обработку нескольких итерируемых объектов. Мы увидели, что map() продолжит обрабатывать несколько итерируемых объектов, пока не достигнет конца объекта, содержащего меньше всего элементов.

Заключение

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

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

Для получения дополнительной информации о Python​​ ознакомьтесь с нашей серией Программирование на Python 3 и посетите нашу тематическую страницу, посвященную Python. Чтобы узнать больше о работе с наборами данных в функциональном программировании, читайте нашу статью о функции filter().