Перейти к основному содержимому

Преобразование коллекции

Преобразование берёт коллекцию, например список или словарь, и строит из неё новую коллекцию. Исходная коллекция не изменяется.

В Python основной инструмент для этого — включение (comprehension): короткое выражение в квадратных скобках, которое строит новый список, или в фигурных скобках — для нового словаря. Большинство преобразований на этой странице занимают одну строку. Встроенные функции zip и enumerate и строковый метод join покрывают остальное.

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


Отображение (map)

Операция map применяет одну и ту же функцию к каждому элементу и собирает ответы в новый список той же длины. Например, она может превратить [1, 2, 3] в [3, 6, 9].

В Python для этого пишут списковое включение: [x * 3 for x in numbers]. Оно читается почти как английская фраза: новый список содержит x * 3 для каждого x в numbers.

Не путайте это со встроенной функцией Python map(), которая делает ту же работу, но принимает объект функции. Здесь «map» означает «применить выражение к каждому элементу».

Map со списковым включением

Включение вычисляет выражение для каждого элемента и собирает результаты в новый список. Здесь оно умножает каждое число на 3.

Prompt
Напишите программу на Python со списком 1, 2, 3. С помощью спискового включения умножьте каждое число на 3 и выведите новый список.
Вывод: полная программа на Python
Map with a list comprehension

Map с индексом

Иногда важна и позиция элемента. enumerate даёт и индекс, и значение, поэтому включение может использовать оба. Здесь каждое значение умножается на свой индекс.

Prompt
Переберите список 1, 2, 3 с помощью enumerate, используя и индекс, и значение. Постройте новый список, в котором каждый элемент равен value * index, затем выведите его.
Вывод: полная программа на Python
Map with the index

Пропуск некоторых результатов

Иногда некоторые результаты нужно отбросить. В Python функция может вернуть None, чтобы сказать «результата нет». Первое включение сохраняет все ответы, включая None. Второе содержит часть if, которая оставляет только результаты, не равные None.

Prompt
Напишите функцию, которая возвращает None для числа 2 и утроенное число в остальных случаях. Примените её к списку 1, 2, 3 и выведите необработанные результаты, затем выведите отфильтрованный список без None.
Вывод: полная программа на Python
Skip some results

Преобразование ключей словаря

Чтобы изменить ключи словаря, постройте новый словарь с помощью словарного включения по items(). Здесь upper() переводит каждый ключ в верхний регистр. Словарь хранит записи в порядке вставки, поэтому вывод всегда идёт в одном и том же порядке.

Prompt
Начните со словаря, в котором "key1" соответствует 1, а "key2" — 2. Постройте новый словарь с теми же значениями, но каждый ключ переведите в верхний регистр с помощью upper(). Выведите новый словарь.
Вывод: полная программа на Python
Transform dictionary keys

Преобразование значений словаря

Чтобы изменить значения, сделайте то же самое, но оставьте ключ и вычислите новое значение. Здесь каждое значение увеличивается на длину своего ключа: 1 + len("key1") равно 5.

Prompt
Начните со словаря, в котором "key1" соответствует 1, а "key2" — 2. Постройте новый словарь с теми же ключами, где каждое значение равно старому значению плюс длина его ключа. Выведите новый словарь.
Вывод: полная программа на Python
Transform dictionary values

Zip

Zip берёт два списка и объединяет их элементы в пары по позиции: первый с первым, второй со вторым и так далее. В результате получается столько пар, сколько элементов в более коротком списке.

В Python есть встроенная функция zip. Она возвращает ленивый итератор кортежей, поэтому оберните её в list(), если хотите увидеть пары или использовать их повторно.

Zip двух списков

zip объединяет в пару один цвет с одним животным и сама останавливается на более коротком списке. Каждая пара — это кортеж, который выводится в круглых скобках.

Prompt
Объедините списки red, brown, grey и fox, bear, wolf поэлементно с помощью встроенной функции zip и выведите полученный список пар.
Вывод: полная программа на Python
Zip two lists

Zip с преобразованием

Сами пары нужны не всегда. Здесь включение проходит по zip(colors, animals) и строит предложение из каждой пары. capitalize() делает первую букву названия животного заглавной.

Prompt
Объедините списки red, brown, grey и fox, bear, wolf поэлементно. Для каждой пары выведите предложение вида "Животное Fox, цвет: red", где первая буква названия животного — заглавная.
Вывод: полная программа на Python
Zip with a transformation

Разделение списка пар (unzip)

Unzip — обратная операция: один список пар превращается в две коллекции. Звёздочка в zip(*number_pairs) распаковывает список, поэтому zip получает три пары как отдельные аргументы и перегруппировывает их первые и вторые части. Оба результата — кортежи.

Prompt
Начните со списка пар: one с 1, two с 2, three с 3. Разделите его на слова и числа с помощью zip(*pairs) и выведите каждый результат на отдельной строке.
Вывод: полная программа на Python
Unzip a list of pairs

Сопоставление (associate)

Сопоставление строит словарь из списка. Каждый элемент даёт один ключ и одно значение. Словарь не может хранить один и тот же ключ дважды, поэтому если два элемента дают одинаковый ключ, побеждает более поздний.

В Python для этого пишут словарное включение: {key: value for element in items}, где ключ и значение вычисляются из каждого элемента.

Элементы как ключи

Сам элемент становится ключом, а значение вычисляется из него. Здесь слова — это ключи, а их длины — значения.

Prompt
Постройте словарь из слов one, two, three, где каждое слово — ключ, а его длина — значение. Выведите словарь.
Вывод: полная программа на Python
Elements as keys

Элементы как значения

Элемент становится значением, а ключ вычисляется из него. Здесь ключ — первая буква в верхнем регистре. И two, и three начинаются с T, поэтому three заменяет two, и в словаре остаются только две записи.

Prompt
Постройте словарь из слов one, two, three, где ключ — первая буква слова в верхнем регистре, а значение — само слово. Выведите словарь и обратите внимание, что "three" заменяет "two" под ключом T.
Вывод: полная программа на Python
Elements as values

Вычисление и ключа, и значения

Из элемента можно вычислить и ключ, и значение. Здесь ключ — первая буква, а значение — длина слова. И снова побеждает более поздняя запись с ключом T.

Prompt
Постройте словарь из слов one, two, three, где ключ — первая буква слова в верхнем регистре, а значение — длина слова. Выведите словарь.
Вывод: полная программа на Python
Compute both key and value

Ключ и значение из одного элемента

Иногда один элемент содержит обе части. split() разрезает полное имя по пробелам на список слов, а распаковка даёт имена обеим частям. Фамилия становится ключом, а имя — значением.

Prompt
Начните с полных имён "Alice Adams" и "Brian Brown". Разбейте каждое имя на слова с помощью split() и постройте словарь, в котором фамилии соответствует имя. Выведите словарь.
Вывод: полная программа на Python
Key and value from one element

Выравнивание (flatten)

Выравнивание превращает вложенную коллекцию, например список списков, в один плоский список со всеми элементами по порядку.

Включение может содержать две части for: [n for inner in number_sets for n in inner]. Читайте их слева направо: для каждого внутреннего списка, для каждого элемента в нём, сохранить элемент.

Выравнивание списка списков

Включение проходит по каждому внутреннему списку и собирает все его элементы в result. Два внутренних списка по три числа превращаются в один список из шести.

Prompt
Начните со списка списков: 1, 2, 3 и 4, 5, 6. Преобразуйте его в один плоский список с помощью вложенного спискового включения, затем выведите его.
Вывод: полная программа на Python
Flatten a list of lists

Выравнивание значений из объектов

Flat map сначала берёт список из каждого элемента, а затем соединяет все эти списки вместе. Здесь первый for проходит по контейнерам, а второй — по c.values. Все значения из трёх контейнеров оказываются в одном списке.

Prompt
Определите класс Container с атрибутом values, который является списком строк. Создайте три контейнера со значениями one, two, three; four, five; и six, seven, eight. Соберите все их значения в один список и выведите его.
Вывод: полная программа на Python
Flatten values from objects

Строковое представление

Часто нужно показать коллекцию в виде читаемого текста, например с запятыми между элементами.

В Python у строки-разделителя есть метод join: ", ".join(words) возвращает одну строку. join принимает только строки, поэтому числа нужно сначала преобразовать, например с помощью str(n) во включении. Дополнительные возможности — префикс, постфикс, ограничение или преобразование — делаются обычной конкатенацией строк или срезом перед соединением.

Соединение с разделителем

join ставит ", " между словами и возвращает одну строку. Обратите внимание, что разделитель стоит первым: это строка, у которой вызывается метод.

Prompt
Соедините слова one, two, three в одну строку с ", " между ними с помощью метода join. Выведите строку.
Вывод: полная программа на Python
Join with a separator

Добавление префикса и постфикса

Префикс и постфикс — это просто текст вокруг соединённого результата. В Python их добавляют с помощью +.

Prompt
Соедините слова one, two, three через " | ", добавьте префикс "начало: " и постфикс ": конец" и выведите результат.
Вывод: полная программа на Python
Add a prefix and a postfix

Ограничение количества элементов

Для длинного списка может понадобиться показать только первые несколько элементов. Срез numbers[:10] берёт первые 10, включение превращает каждый из них в строку с помощью str(n), а "<...>" в конце показывает, что остальные элементы были отрезаны.

Prompt
Создайте список с числами от 1 до 100. Соедините через ", " только первые 10 из них и добавьте "<...>" в конце, чтобы показать, что список обрезан. Выведите результат.
Вывод: полная программа на Python
Limit the number of elements

Преобразование каждого элемента перед соединением

Чтобы изменить каждый элемент перед соединением, постройте включением новый список строк, а затем вызовите для него join. Здесь каждое слово превращается в "Элемент: " плюс слово в верхнем регистре.

Prompt
Превратите каждое из слов one, two, three в "Элемент: ", за которым следует слово в верхнем регистре. Соедините результаты через ", " и выведите строку.
Вывод: полная программа на Python
Transform each element before joining