7 уровней использования функции zip в Python
- Просмотры: 2800
- Категория: Python
- Создано: 16 февраля 2021
- Тэги:
В Python есть несколько встроенных функций, которые могут сделать наш код довольно элегантным. Одна из них – функция zip. Однако, использование этой функции не совсем понятно для начинающих и при её использовании они часто совершают ошибки.
Например, пусть имеется 2х3 матрица, представленная в виде вложенного списка:
matrix = [[1, 2, 3], [1, 2, 3]]
Популярный вопрос на собеседованиях по Python
Как транспонировать эту матрицу?
Джуниор разработчики могут написать для этого несколько циклов for. Однако сениор разработчику для этого понадобится одна строчка кода:
matrix_T = [list(i) for i in zip(*matrix)]
Элегантно, не правда ли?
Если вы пока не понимаете приведённое выше однострочное решение, не переживайте. Эта статья далее объяснит данный код. Мы также рассмотрим на 7 уровнях концепцию, применение и советы по использованию мощной функции zip.
Если вы уже знакомы с приведённым выше решением, но хотите узнать другие замечательные приёмы использования функции zip, то эта статья – ваша чашка чая.
Уровень 0: Базовое использования функции Zip
Функция zip объединяет элементы различных итерируемых объектов, таких как списки, кортежи или множеств, и возвращает итератор.
Например, мы можем использовать её, чтобы скомбинировать два списка следующим образом:
Как показано в примере выше, функция zip возвращает итератор на основе кортежа, где i-й кортеж содержит i-е элементы из каждого списка.
Эта функция напоминает работу застёжки «молнии», не правда ли?
Уровень 1 . Меньше-больше итерируемых объектов за один раз
Фактически, функция zip в Python намного мощнее обычной застёжки-«молнии». Она может работать с любым количеством итерируемых объектов за один раз, а не только с двумя.
Если мы передадим один список в функцию zip, получим
А как насчёт трёх списков?
Как мы указывали выше, не имеет значение, сколько итерируемых объектов мы передаём в функцию zip, она просто работает так, как от неё и ожидается.
Между прочем, если не передать ни одного аргумента в zip функцию, она просто вернёт пустой итератор.
Уровень 2. Работаем с неравными по длине аргументами
Реальные данные не всегда чистые и полные, иногда мы вынуждены работать с неравными по длине итерируемыми объектами. По умолчанию, результат работы zip функции основан на самом коротком итерируемом объекте.
Как показано в коде выше, самый короткий список – это id, поэтому record содержит только два кортежа, а последние два лидера в списке leaders были проигнорированы.
Но что делать, если последние два лидера обидятся на нас, если мы их проигнорируем?
Python снова поможет нам. Существует другая функция в модуле itertools, которая называется zip_longest. Как говорит её имя, она является сестрой функции zip, а её результат основывается на самом длинном аргументе.
Давайте применим zip_longest для того, чтобы сгенерировать список record
Как говорилось выше, результат функции zip_longest основывается на самом длинном аргументе. Опциональный аргумент fillvalue, у которого значение по умолчанию None, может помочь нам заполнить потерянные значения.
Уровень 3. Обратная операция unzip
Пусть, как в предыдущем примере, мы сначала получили список record. Как мы можем раззиповать его по отдельным итерируемым объектам?
К сожалению, в Python нет функции unzip. Однако, если мы знакомы с приёмам работы со звёздочкой, «раззипирование» становится очень лёгкой задачей.
В приведённом выше примере звёздочка выполнят операцию распаковывания: она распаковывает все четыре кортежа из списка record.
Если мы не хотим использовать «звёздную» технику, то тогда мы должны действовать так.
Уровень 4. Создание и обновление словарей с помощью функции zip
С помощью функции zip очень легко создавать или обновлять на основе отдельных списков словари. Здесь имеются два однострочных решения:
- Использование dict comprehension и zip
- Использование функции dict и zip
Указанный пример выше вообще не использует цикл for. Как это элегантно и «питонистично»!
Уровень 5. Использование функции zip в циклах for
Часто приходится обрабатывать много итерируемых объектов за один раз. Здесь функция zip вместе с циклом for может прийти нам на помощь.
Давайте рассмотрим следующий пример:
Есть ли более элегантный метод решить эту задачу?
Уровень 6. Получить транспонированную матрицу
Наконец, возвращаемся к вопросу из собеседования по Python
Как получить транспонированную матрицу?
Так как мы уже знаем функцию zip, распаковывание с помощью одинарной звёздочки, и list comprehension, то однострочное решение становится почти очевидным
Вывод
Функция zip в Python очень полезная и мощная. Используя её свойства, мы можем писать меньше кода и делать больше операций. «Делать большее с помощью меньшего» - это философия Python.
Мой перевод статьи Yang Zhou: 7 Levels of Using the Zip Function in Python