Курс по 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():
Здесь функция 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() мы также с
итератором можем применять некоторые другие функции, которые в качестве
аргумента принимают итерированный объект, например:
Но, если следом
попытаться перебрать итератор еще раз:
то увидим
значение 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() указываем эту
функцию:
(Обратите
внимание, без круглых скобок, то есть, передаем ссылку на нее, а не вызываем).
И после запуска программы увидим наборы вложенных списков из отдельных символов
исходных строк.
Конечно, если
функция выполняет какую-либо простую операцию, то часто прописывают
лямбда-функции непосредственно в 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