Функция map. Примеры ее использования

Курс по Python: https://stepik.org/course/100707

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

Вначале я приведу простой пример использования функции map() для преобразования строк чисел в обычные числа:

b = map(int, ['1', '2', '3', '5', '7'])

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

Вернемся к нашей программе и ниже дважды вызовем функцию next() для итератора b:

print(next(b))
print(next(b))

В консоли видим первые два преобразованных значения. Давайте переберем все их с помощью цикла for:

for x in b:
    print(x, end=" ")

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

Мы также легко можем сохранить результат преобразования в новом списке, используя функцию list():

a = list(b)
print(a)

Здесь функция list() автоматически перебрала итератор, неявно вызывая функцию next(), и сформировала соответствующие значения списка.

Этот же результат можно получить, используя генератор списка, следующим образом:

a = [int(x) for x in ['1', '2', '3', '5', '7']]
print(a)

Но здесь, в отличие от функции map() мы все значения уже храним в памяти, тогда как функция map() возвращает итератор и значения формируются по одному в процессе вызова функции next().

А вот эквивалентный генератор:

a = (int(x) for x in ['1', '2', '3', '5', '7'])

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

Далее, кроме функции list() мы также с итератором можем применять некоторые другие функции, которые в качестве аргумента принимают итерированный объект, например:

print(sum(b))

Но, если следом попытаться перебрать итератор еще раз:

print(sum(b))

то увидим значение 0, так как мы помним, что итератор можно перебирать только один раз. Вот это следует помнить, используя функцию map() – ее значения можно извлечь только один раз.

Вместо функции sum() можно также использовать функции max() и min()

print(max(b))
print(min(b))

И другие, которые работают с итерируемыми последовательностями.

Конечно, вместо функции int() мы можем использовать любую другую, которая принимает один аргумент и возвращает некоторое значение. Например, можем взять список городов:

cities = ["Москва", "Астрахань", "Самара", "Уфа", "Смоленск", "Тверь"]

и применить к его элементам функцию len(), следующим образом:

b = map(len, cities)
print(list(b))

Видите, как легко и просто записан генератор для преобразования списка cities? В этом и заключается удобство использования функции map().

Также мы можем применять к этим строкам их методы, например, переведем все в верхний регистр:

b = map(str.upper, cities)

Мы здесь указали объект str и его метод upper(), который возвращает новую строку со всеми заглавными буквами.

Также мы можем определять и свои функции, используемые в map(). Как я уже отмечал, функция обязательно должна принимать один аргумент и возвращать некоторое значение, например, так:

def symbols(s):
    return list(s.lower())

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

b = map(symbols, cities)

(Обратите внимание, без круглых скобок, то есть, передаем ссылку на нее, а не вызываем). И после запуска программы увидим наборы вложенных списков из отдельных символов исходных строк.

Конечно, если функция выполняет какую-либо простую операцию, то  часто  прописывают лямбда-функции непосредственно в map(). В нашем случае это можно сделать так:

b = map(lambda s: list(s.lower()), cities)

Результат будет прежним, а программа стала более простой и читабельной.

Или, можно преобразовать строки, записав их символы в обратном порядке:

b = map(lambda s: s[::-1], cities)

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

Ну и теперь, возвращаясь к уже знакомой нам конструкции:

s = map(int, input().split())
print(list(s))

(Я ее записал здесь в две строки, чтобы было понятнее.) Вы понимаете, как она работает. Здесь input().split() возвращает список из строк введенных чисел, к каждой строке применяется функция int() и с помощью функции list() генератор s превращается в список из чисел.

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

Курс по Python: https://stepik.org/course/100707

Видео по теме