Начало работы с картой | Кодементор
Хотя это, безусловно, менее распространено, вполне возможно писать код Python в функциональном стиле, и в стандартной библиотеке Python есть множество инструментов для облегчения функционального программирования. Один из таких инструментов называется map
и в этом посте мы посмотрим, что map
предназначен для, и как вы можете использовать его в своем собственном коде.
Что значит map
делать?
Проще говоря, map
используется для многократного вызова функции, каждый раз передавая новый аргумент из набора объектов. Например, у нас может быть такой список целых чисел:
numbers = [1, 3, 4, 2, 11, 6]
Здесь мы могли бы использовать map
удвоить каждое из целых чисел в numbers
список. В этом случае мы хотим вернуть 6 чисел: 2, 6, 8, 4, 22 и 12 соответственно.
Жизнь без map
Прежде чем мы посмотрим на map
реализация этого, как мы могли бы решить эту проблему без карты? Ну, мы можем использовать старый добрый цикл for.
numbers = [1, 3, 4, 2, 11, 6]
doubled_numbers = []
for number in numbers:
addition_results.append(number * 2)
Это, безусловно, работает, но если вы читали мой пост о пониманиях, вы точно знаете, что мы собираемся сделать, чтобы сделать это еще лучше:
numbers = [1, 3, 4, 2, 11, 6]
doubled_numbers = [number * 2 for number in numbers]
А map
реализация
Теперь, когда мы рассмотрели альтернативы, как нам реализовать этот процесс удвоения с помощью карты?
Вначале давайте посмотрим на длинный путь. Во-первых, мы собираемся определить функцию с именем double
который позаботится обо всей логике за нас. double
будет иметь один параметр и вернет двойное значение числа, переданного в функцию:
def double(x):
return x * 2
numbers = [1, 3, 4, 2, 11, 6]
Мы, безусловно, могли бы сделать гораздо больше с этой функцией. Мы могли бы добавить обработку ошибок и все такое прочее, но для нашего примера этого вполне достаточно.
Теперь у нас есть настроенная функция, мы можем использовать map
. map
имеет два обязательных параметра: первый — это вызываемая функция, а второй — итерируемый объект, такой как список или строка.
Имея это в виду, мы можем реализовать нашу map
решение так:
def double(x):
return x * 2
numbers = [1, 3, 4, 2, 11, 6]
doubled_numbers = map(double, numbers)
Здесь есть несколько вещей, на которые следует обратить внимание. Во-первых, мы не звонили double
функция при передаче ее в качестве аргумента map
; вместо этого мы просто передали функцию имя. map
собирается сделать призвание для нас.
Второе замечание в настоящее время скрыто. Какова ценность doubled_numbers
? Что ж, проверим:
print(doubled_numbers)
Это, конечно, не то, что мы хотели. Что случилось со всеми нашими номерами?
map
на самом деле возвращает итератор, а не коллекцию, как список. Это означает, что мы можем получить доступ к значениям по одному, используя что-то вроде next
:
print(next(doubled_numbers))
print(next(doubled_numbers))
Если мы хотим, чтобы все наши значения сразу были в чем-то вроде списка, мы можем просто преобразовать объект карты, используя соответствующую фабричную функцию:
doubled_numbers = list(map(double, numbers))
print(doubled_numbers)
Ранее я говорил, что это долгий путь, поэтому далее мы рассмотрим, как можно немного сократить код.
map
с лямбда-функциями
Для более простых операций, таких как наша double
функцию, мы, вероятно, не будем беспокоиться о полном определении функции. Это если мы не собирались использовать его в нескольких местах нашего кода. Если это не так, мы можем использовать лямбда-функцию непосредственно внутри map
вместо.
Используя лямбду, наш map
решение может выглядеть так:
numbers = [1, 3, 4, 2, 11, 6]
doubled_numbers = map(lambda x: x * 2, numbers)
Как видите, это сократило наше решение до пары строк. Мы могли бы сделать его еще короче, поместив numbers
список прямо в map
функция.
Передача нескольких итераций в map
Одна интересная вещь с map
заключается в том, что он может обрабатывать более одной итерации за раз. Когда мы делаем это, map
будет собирать по одному элементу из каждой итерации для каждой итерации, пока не достигнет конца одной из этих итераций. Это похоже на использование zip в цикле.
Давайте посмотрим на пример:
numbers_1 = [7, 1, 3]
numbers_2 = [5, 8, 4]
addition_results = list(map(lambda a, b: a + b, numbers_1, numbers_2))
В приведенном выше коде у нас есть два списка чисел, оба из которых мы передаем в map
. Функция, которую мы вызываем для каждой итерации, представляет собой лямбда-функцию, которая берет число из numbers_1
номер из numbers_2
а затем возвращает сумму.
Мы можем сделать это с произвольным количеством итераций, нам просто нужно убедиться, что функция, которую мы хотим запустить, может обрабатывать количество аргументов, которые мы будем ей передавать.
Если вы используете map
?
Прежде чем закончить этот пост, я просто хотел сказать несколько слов об использовании map
в вашем собственном коде.
Во-первых, это определенно важно знать, потому что вы столкнетесь с map
много в дикой природе, даже если вы лично не хотите его использовать.
Что касается того, должен использовать map
, это действительно зависит. Для меня синтаксис понимания, как правило, намного понятнее, чем использование map
в большинстве случаев. Учитывая, насколько важна удобочитаемость, я обычно избегаю map
но это только я.
Однако бывают случаи, когда полное понимание может быть немного многословным, учитывая, насколько просты операции, которые мы выполняем. В таких случаях может быть map
было бы лучше. Это действительно зависит от контекста.
Менее важно то, что map
очень часто немного быстрее, чем понимание. Таким образом, если вы имеете дело с критической частью вашего приложения с высокой производительностью, вы можете рассмотреть map
над пониманием. Что, как говорится, всегда тестируйте свой собственный код, потому что иногда map
просто медленнее.
Просто некоторые вещи, чтобы рассмотреть.
Подведение итогов
С этим мы закончили! Это все, что нужно знать, когда дело доходит до начала работы. map
. Конечно, есть гораздо более сложные способы использования map
, и мы также можем выполнять гораздо более сложные операции. Небо это предел.
Если вам интересно узнать больше о функциональном программировании на Python, я бы порекомендовал взглянуть на фильтр а также уменьшать в официальной документации. Вы также можете взглянуть на инструменты, itertoolsи модуль оператора.
Надеюсь, вы узнали что-то новое, и я поймаю вас в следующий раз.