Функция zip() в Python — как работает
В этом уроке вы узнаете, как использовать функцию Python zip() для выполнения параллельных итераций над несколькими итерируемыми объектами.
- Введение в функцию Python zip()
- Итерируемые объекты разных размеров
- Распаковка итерируемого объекта с помощью функции zip()
Введение в функцию Python zip()
Предположим, у вас есть два кортежа: names и ages.
- Кортеж names хранит список имен.
- Кортеж ages хранит список возрастов.
Чтобы сопоставить имена и возрасты из этих кортежей один за другим в последовательности, вы можете использовать функцию enumerate(). Например:
names =('John', 'Jane', 'Alice') ages =(20, 22, 25) for index, name in enumerate(names): print((name, ages[index]))
Выход:
('John', 20) ('Jane', 22) ('Alice', 25)
Итак, Джону 20, Джейн 22, а Элис 25.
Однако, все становится сложнее, если размеры кортежей имен и возрастов различаются. Вот почему в игру вступает функция zip().
Ниже показан синтаксис функции zip():
zip(*iterables, strict=False)
Функция zip() выполняет итерацию нескольких итерируемых объектов параллельно и возвращает кортежи, содержащие элементы из каждого итерируемого объекта. Другими словами, функция zip() возвращает итератор кортежей, где i-й кортеж содержит i-й элемент из каждой входной итерируемой переменной.
В следующем примере показано, как использовать функцию zip() для перебора кортежей имен и возрастов:
names =('John', 'Jane', 'Alice') ages =(20, 22, 25) for employee in zip(names, ages): print(employee)
Выход:
('John', 20) ('Jane', 22) ('Alice', 25)
В этом примере zip() возвращает кортеж в каждой итерации и присваивает его переменной employee. Кортеж содержит i-е элементы — кортежи names и ages.
Функция zip() возвращает объект zip, который является итератором:
names =('John', 'Jane', 'Alice') ages =(20, 22, 25) employees = zip(names, ages) print(type(employees)) # 👉 <class 'zip'>
Zip() ленивый. Это означает, что Python не будет обрабатывать элементы, пока вы не выполните итерацию итерируемого. Для итерации итерируемого вы можете использовать:
- Цикл for
- Вызов функции next()
- Упаковка в list()
Например:
names =('John', 'Jane', 'Alice') ages =(20, 22, 25) employees = zip(names, ages) employee_list = list(employees) print(employee_list) # 👉 [('John', 20),('Jane', 22),('Alice', 25)]
Итерируемые объекты разных размеров
Итерации, переданные в функцию zip(), могут иметь разные размеры. У zip() есть три разные стратегии для решения этой проблемы.
По умолчанию метод zip() остановится, когда завершит итерацию самого короткого итерируемого объекта. Он проигнорирует оставшиеся элементы в более длинных итерируемых объектах. Например:
names =('John', 'Jane', 'Alice', 'Peter') ages =(20, 22, 25) for name, age in zip(names, ages): print(name, age)
Выход:
John 20 Jane 22 Alice 25
В этом примере функция zip() выполняет три итерации на основе наименьшего размера имен и возрастов.
Если вы хотите гарантировать, что итерируемые объекты должны иметь одинаковые размеры, вы можете использовать опцию strict=True. В этом случае, если размеры итерируемых объектов различаются, zip() вызовет ValueError.
Обратите внимание, что аргумент strict доступен с версии Python 3.10.
Например, следующий код вызовет исключение ValueError, поскольку размеры итерируемых объектов различны:
names =('John', 'Jane', 'Alice', 'Peter') ages =(20, 22, 25) for name, age in zip(names, ages, strict=True): # ValueError 🛑 print(name, age)
Выход:
ValueError: zip() argument 2 is shorter than argument 1
Если итерируемые объекты имеют неравномерный размер и вы хотите заполнить отсутствующие значения с помощью fillvalue, вы можете использовать функцию zip_longest() из модуля itertools:
itertools.zip_longest(*iterables, fillvalue=None)
По умолчанию fillvalue — None. Например:
from itertools import zip_longest names =('John', 'Jane', 'Alice', 'Peter') ages =(20, 22, 25) for name, age in zip_longest(names, ages): print(name, age)
Выход:
John 20 Jane 22 Alice 25 Peter None
Распаковка итерируемого объекта с помощью функции zip()
Распаковка отменяет сжатие, преобразуя сжатые значения обратно в индивидуальные значения. Для распаковки используется функция zip() с оператором распаковки(*). Например:
employees =(('John', 20),('Jane', 22),('Alice', 25)) names, ages = zip(*employees) print(names) print(ages)
Выход:
('John', 'Jane', 'Alice') (20, 22, 25)
В этом примере у нас есть кортеж, где каждый элемент содержит имя и возраст. Функция zip() распаковывает кортеж, чтобы создать два разных кортежа (имена и возраст).