Знакомство с map, filter и reduce — Python: Функции
Функции высшего порядка map , filter и reduce — это наиболее распространенные и мощные инструменты в программировании. Они позволяют работать с коллекциями данных. Эти функции упрощают и ускоряют работу с данными, позволяют писать более чистый и эффективный код.
В этом уроке мы рассмотрим подробно каждую из этих функций и научимся применять их в практических задачах.
Map
Допустим, мы хотим применить к каждому элементу списка чисел функцию или операцию. Мы можем использовать цикл for , чтобы пройтись по элементам списка и применить операции к каждому элементу.
Например, у нас есть список чисел. Мы хотим получить новый список, в котором каждый элемент будет возводиться в квадрат, а затем вычитаться десять. Мы можем решить эту задачу через цикл:
numbers = [1, 2, 3, 4, 5] new_numbers = [] for num in numbers: squared = num ** 2 subtracted = squared - 10 new_numbers.append(subtracted) print(new_numbers) # [-9, -6, -1, 6, 15]
У такого подхода есть недостатки: код становится громоздким, трудно читаемым и поддерживаемым.
В этом случае можно воспользоваться функцией map , которая позволяет применить функцию к каждому элементу коллекции. Она вернет новый список с преобразованными значениями.
map означает «отобразить». Это название пришло из математики, где так же называется функция, которая отображает одно множество значений в другое путем преобразования всех элементов с помощью трансформации. В большинстве языков также используется это имя.
Рассмотрим реализацию функции map :
def map(func, iterable): result = [] for item in iterable: result.append(func(item)) return result
Этот цикл похож на цикл из примера выше. Здесь мы создаем пустой список result и затем циклом проходимся по элементам переданного итерируемого объекта iterable . Для каждого элемента мы вызываем функцию func и добавляем ее результат в список result . По завершении цикла мы возвращаем список result .
Теперь попробуем применить функцию map к нашей задаче:
def process_number(num): squared = num ** 2 subtracted = squared - 10 return subtracted numbers = [1, 2, 3, 4, 5] new_numbers = map(process_number, numbers) print(new_numbers) # [-9, -6, -1, 6, 15]
В данном примере мы сначала определили функцию process_number , которую хотим применить к каждому элементу списка. Далее передали ее со списком numbers в функцию map .
Функция map позволила нам более эффективно и лаконично обработать коллекцию данных. Она применила функцию к каждому элементу коллекции и вернула новый список с преобразованными значениями.
Далее рассмотрим функцию filter .
Filter
Часто в программировании нужно отфильтровать коллекцию данных — то есть выбрать из коллекции только те элементы, которые удовлетворяют определенным условиям.
Например, если у нас есть список чисел и мы хотим получить только те, которые больше пяти, то мы можем использовать цикл for , чтобы пройтись по элементам списка и проверить условия для каждого элемента:
numbers = [2, 7, 1, 8, 4, 5] result = [] for num in numbers: if num > 5: result.append(num) print(result) # [7, 8]
При этом у такого подхода тоже есть свои недостатки: код становится громоздким и трудночитаемым.
В этом случае можно воспользоваться функцией filter . Она позволяет отфильтровать элементы коллекции на основе заданного условия и вернуть новую коллекцию с элементами, которые удовлетворяют этому условию. Многие языки имеют аналогичную функцию с тем же именем.
Реализация функции filter аналогична реализации функции map :
def filter(func, iterable): result = [] for item in iterable: if func(item): result.append(item) return result
Здесь мы создаем пустой список result и затем циклом проходимся по элементам переданного итерируемого объекта iterable . Для каждого элемента мы вызываем функцию func и проверяем, удовлетворяет ли он заданному условию. Если условие выполняется, то мы добавляем элемент в список result . По завершении цикла мы возвращаем список result .
Теперь рассмотрим пример использования функции filter . Допустим, у нас есть список чисел, и мы хотим получить только те числа, которые больше пяти:
def greater_than_five(num): return num > 5 numbers = [2, 7, 1, 8, 4, 5] result = filter(greater_than_five, numbers) print(result) # [7, 8]
Здесь мы сначала определили функцию greater_than_five , которая возвращает True , если переданный ей аргумент больше пяти. Далее передали ее со списком numbers в функцию filter .
Так функция filter упростила код и повысила его читаемость и дальнейшее сопровождение.
Теперь рассмотрим функцию reduce .
Reduce
Последняя функция из нашей тройки — reduce() (говорят «свертка»), который используется для агрегации данных. Под агрегацией понимается операция, вычисляющая значение, зависящее от всего набора данных. С помощью функции reduce можно последовательно применить операции к элементам списка, чтобы получить единственное значение. Допустим, у нас есть список чисел, и мы хотим получить их сумму. В этом случае мы можем использовать цикл for , чтобы последовательно складывать каждый элемент списка. Например:
numbers = [1, 2, 3, 4, 5] result = 0 for num in numbers: result += num print(result) # 15
В данном примере мы объявляем переменную result и присваиваем значение 0. Затем циклом for проходим по всем элементам списка numbers . Каждый элемент списка numbers прибавляем к значению переменной result . После завершения цикла в переменной result у нас хранится сумма всех элементов списка numbers .
Теперь рассмотрим пример, когда нам нужно перемножить все элементы в списке. Мы также можем решить эту задачу через цикл:
numbers = [1, 2, 3, 4, 5] result = 1 for num in numbers: result *= num print(result) # 120
Здесь у нас код похож на сложение всех элементов списка. Отличие — начальное значение переменной result и операция, которую мы выполняем.
Теперь улучшим код для этих двух примеров. Воспользуемся функцией reduce , которая позволяет последовательно применять операцию к элементам списка, возвращая единственное значение.
Рассмотрим реализацию функции reduce :
def reduce(func, iterable, initial): result = initial for item in iterable: result = func(result, item) return result
В данном примере на вход функции reduce передаются три аргумента:
- func — функция, которую мы будем применять к элементам iterable
- iterable — итерируемый объект, элементы которого мы будем обрабатывать функцией func
- initial — начальное значение, которое будет использоваться при первом вызове функции func
Внутри функции создаем переменную result , которой в качестве начального значения передаем значение initial . Затем циклом for проходим по всем элементам объекта iterable и каждый элемент вместе со значением result передаем в функцию func . Результат функции func записываем в переменную result . Результатом работы функции reduce будет финальное значение переменной result .
Теперь рассмотрим пример использования функции reduce , чтобы найти сумму и произведение элементов списка:
def add(x, y): return x + y def multiply(x, y): return x * y numbers = [1, 2, 3, 4, 5] result = reduce(add, numbers, 0) print(result) # 15 result = reduce(multiply, numbers, 1) print(result) # 120
Здесь мы создали две функции add и multiply , чтобы сложить и перемножить два числа. Далее мы используем функцию reduce , чтобы получить результат применения функций add и multiply к элементам списка numbers .
При первом вызове функции reduce мы передаем начальное значение 0, а при втором вызове — значение 1. Так нам удалось сократить и сделать более читаемый код.
Map, filter и reduce против цикла for
Мы можем реализовать любую логику в цикле for , но этот инструмент не всегда удобный или понятный. Например, если нам нужно преобразовать каждый элемент списка, то использование цикла for может вызвать проблемы с читаемостью кода и его поддержкой в будущем.
В этом случае мы можем воспользоваться функцией map , которая позволяет применить функцию к каждому элементу списка и вернуть новый список с преобразованными значениями. Также для выбора элементов по определенному условию вместо цикла for можно использовать функцию filter , которая вернет элементы, удовлетворяющие заданному условию.
Если нам нужно произвести агрегацию значений списка, например, сложить или умножить все его элементы, то для этого необязательно использовать цикл for . В этом случае можно воспользоваться функцией reduce , которая последовательно применяет заданную функцию к парам элементов списка и возвращает окончательный результат.
Цикл не всегда можно заменить на функции map , filter или reduce . Но если речь идет о простых манипуляциях со списками, то использование этих функций может значительно упростить чтение, написание и понимание кода. Еще это помогает избежать ошибок в логике и сделать код более читаемым и поддерживаемым в будущем, так как каждая функция делает одну работу.
Выводы
В этом уроке мы рассмотрели три функции: map , filter и reduce . Это более простой и лаконичный способ выполнить операции, которые могут быть выполнены также с помощью цикла for .
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Функция map() в Python, обработка последовательности без цикла
Применяет определенную функцию к каждому элементу в последовательности
Синтаксис:
map(function, iterable, . )
Параметры:
- function — пользовательская функция, вызывается для каждого элемента,
- iterable — последовательность или объект, поддерживающий итерирование.
Возвращаемое значение:
- map object — объект итератора.
Описание:
Функция map() выполняет пользовательскую функцию function для каждого элемента последовательности, коллекции или итератора iterable . Каждый элемент iterable отправляется в функцию function в качестве аргумента.
Если в map() передаётся несколько iterable , то пользовательская функция function должна принимать количество аргументов, соответствующее количеству переданных последовательностей, при этом function будет применяться к элементам из всех итераций параллельно.
# функция должна принимать столько # аргументов, сколько последовательностей # передается в функцию map() def plus(a, b, c): return a + b +c # функция 'plus' применяется к элементам # из всех последовательностей параллельно >>> x = map(plus, [1, 2], [3, 4], [5, 6]) >>> list(x) # [9, 12]
При использовании нескольких последовательностей, функция map() останавливается, когда исчерпывается самая короткая итерация.
def create_tuple(a, b): return a, b # функция `map()` останавливается, когда # заканчивается самая короткая последовательность >>> x = map(create_tuple, ['a', 'b'], [3, 4, 5]) >>> print(dict(x)) #
Можно также использовать любую встроенную функцию с функцией map() при условии, что функция принимает аргумент и возвращает значение.
>>> x = [1, 2, 3] >>> y = [4, 5, 6, 7] # вычисление при помощи встроенной функции 'pow()' # 'x' в степени 'y' для каждого элемента 2-х списков >>> list(map(pow, x, y)) # [1, 32, 729]
Для случаев, когда входные данные функции уже организованы в кортежи аргументов, смотрите функцию itertools.starmap() .
Преимуществ использования map() :
- Так как функция map() написана на языке C и хорошо оптимизирована, ее внутренний цикл более эффективный, чем обычный цикл for в Python.
- Низкое потребление памяти. С помощью цикла for .. in: программе необходимо хранить в памяти системы весь список элементов последовательности над которым производятся какие-то действия внутри цикла. При помощи функции map() элементы последовательности извлекаются по запросу, следовательно при каждом внутреннем цикле map() в памяти системы находится и обрабатывается только один элемент последовательности.
Примеры обработки последовательностей без циклов.
- Подсчет количества символов в каждом элементе кортежа;
- Создание словаря из двух списков;
- Удаление пунктуации в тексте.
Подсчет количества символов в каждом элементе кортежа:
>>> x = map(len, ('apple', 'banana', 'cherry')) >>> list(x) # [5, 6, 6]
Создание словаря из двух списков.
>>> x = map(lambda *args: args, [1, 2], [3, 4]) >>> dict(x) #
Удаление пунктуации в тексте при помощи map() .
>>> import re >>> def clean(word): . return re.sub(r"[`. ;,'\"()-]", "", word.strip()) >>> text = """С помощью цикла `for .. in:` программе необходимо хранить в памяти системы весь (список)! """ >>> word = text.split() >>> word = map(clean, word) >>> text = ' '.join(word) >>> text # 'С помощью цикла for in программе необходимо # хранить в памяти системы весь список'
- ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
- Функция abs(), абсолютное значение числа
- Функция all(), все элементы True
- Функция any(), хотя бы один элемент True
- Функция ascii(), преобразует строку в ASCII
- Функция bin(), число в двоичную строку
- Класс bool(), логическое значение объекта
- Функция breakpoint(), отладчик кода
- Класс bytearray(), преобразует в массив байтов
- Класс bytes(), преобразует в строку байтов
- Функция callable(), проверяет можно ли вызвать объект
- Функция chr(), число в символ Юникода
- Класс classmethod, делает функцию методом класса
- Функция compile() компилирует блок кода Python
- Класс complex(), преобразует в комплексное число
- Функция delattr(), удаляет атрибут объекта
- Класс dict() создает словарь
- Функция dir(), все атрибуты объекта
- Функция divmod(), делит числа с остатком
- Функция enumerate(), счетчик элементов последовательности
- Функция eval(), выполняет строку-выражение с кодом
- Функция exec(), выполняет блок кода
- Функция filter(), фильтрует список по условию
- Класс float(), преобразует в вещественное число
- Функция format(), форматирует значение переменной
- Класс frozenset(), преобразует в неизменяемое множество
- Функция getattr(), значение атрибута по имени
- Функция globals(), переменные глобальной области
- Функция hasattr(), наличие атрибута объекта
- Функция hash(), хэш-значение объекта
- Функция help(), справка по любому объекту
- Функция hex(), число в шестнадцатеричную строку
- Функция id(), идентификатор объекта
- Функция input(), ввод данных с клавиатуры
- Класс int(), преобразует в тип int
- Функция isinstance(), принадлежность экземпляра к классу
- Функция issubclass(), проверяет наследование класса
- Функция iter(), создает итератор
- Функция len(), количество элементов объекта
- Класс list(), преобразовывает в список
- Функция locals(), переменные локальной области
- Функция map(), обработка последовательности без цикла
- Функция max(), максимальное значение элемента
- Класс memoryview(), ссылка на буфер обмена
- Функция min(), минимальное значение элемента
- Функция next(), следующий элемент итератора
- Класс object(), возвращает безликий объект
- Функция oct(), число в восьмеричную строку
- Функция open(), открывает файл на чтение/запись
- Функция ord(), число символа Unicode
- Функция pow(), возводит число в степень
- Функция print(), печатает объект
- Класс property(), метод класса как свойство
- Класс range(), генерирует арифметические последовательности
- Функция repr(), описание объекта
- Функция reversed(), разворачивает последовательность
- Функция round(), округляет число
- Класс set(), создает или преобразовывает в множество
- Функция setattr(), создает атрибут объекта
- Класс slice(), шаблон среза
- Функция sorted(), выполняет сортировку
- Декоратор staticmethod(), метод класса в статический метод
- Класс str(), преобразует объект в строку
- Функция sum(), сумма последовательности
- Функция super(), доступ к унаследованным методам
- Класс tuple(), создает или преобразует в кортеж
- Класс type(), возвращает тип объекта
- Функция vars(), словарь переменных объекта
- Функция zip(), объединить элементы в список кортежей
- Функция __import__(), находит и импортирует модуль
- Функция aiter(), создает асинхронный итератор
- Функция anext(), следующий элемент асинхронного итератора
Что делает функция map в Python?
Функция map принимает в качестве аргументов какую-либо функцию и итерируемый объект. Далее каждый элемент коллекции передается в эту функцию в качестве аргумента, где с ним происходят операции, в соответствии с кодом функции:
# объявим функцию, которая возвращает длину объекта def myfunc(a): return len(a) # с помощью нашей функции посчитаем # длину каждого слова в коллекции x = map(myfunc, ('apple', 'banana', 'cherry')) print(x) # => print(list(x)) # => [5, 6, 6]
def myfunc(a, b): return a + b x = map(myfunc, ('apple', 'banana', 'cherry'), ('orange', 'lemon', 'pineapple')) print(list(x)) # => ['appleorange', 'bananalemon', 'cherrypineapple']
Что делает map в python
Функция map является встроенной функцией языка и имеет следующий синтаксис:
map(func, *iterables) --> map object
Функция map принимает в качестве первого аргумента объект функцию, а в качестве второго аргумента — любой итерируемый объект, к которым относятся списки, кортежи, словари и т.д. И функция map будет вычислять значение функции, которую вы ей передали, над каждым элементом последовательности и вернет в качестве результата итератор map object, который легко можно будет преобразовать к списку или любой другой последовательности.
В примере выше мы передавали в качестве функции встроенную функцию abs, которая должна принимать одно значение и возвращать модуль числа. При передачи мы не указывали ни скобок после abs, ни передаваемого значения. Функция map будет сама брать поочередно значение из списка a и передавать его нашей функции abs.
В качестве функции вы также можете передавать собственные функции, которые вы создали при помощи инструкции def.
Ниже пример использования встроенной функции len для списка из строк.
Также в качестве функции вы можете передавать встроенные методы объектов. Например, у строк есть метод .upper(), который преобразует все буквы к большому регистру. Чтобы его передать, вы должны обратиться к встроенному объекту str и через точку написать название метода.
Также можно передавать в качестве функции lambda-выражения.
И пример ниже показывает как можно ввести несколько значений через пробел в одной строке