Модуль itertools является одной из самых мощных фич Python, предоставляющий эффективные функции, которые работают с итераторами, то есть создают объекты, по которым можно пройтись в цикле (for
или while
). Одной из таких полезных функций является itertools.zip_longest()
. Эта функция позволяет объединять несколько итераторов, таких как списки или кортежи, в один итератор, заполняя "недостающие" значения, если итераторы имеют разную длину.
Функция
itertools.zip_longest()
принимает два или более итерируемых объекта и объединяет их в один итератор, состоящий из кортежей. Каждый кортеж содержит элементы из всех исходных итераторов, которые стоят на одной и той же позиции.
Основное отличие zip_longest()
от встроенной функции zip()
заключается в том, что zip_longest()
продолжает объединение до самого длинного итератора, заполняя недостающие значения неким "заполнителем".
Синтаксис
itertools.zip_longest(*iterables, fillvalue=None)
Параметры:
*iterables
- целевые итерируемые объекты, которые нужно совместить.fillvalue
(необязательно) - значение, которым будут заполнены пустующие позиции в случае разной длины итерируемых объектов. По умолчанию None
.import itertools
numbers = [1, 2, 3, 4]
letters = ['a', 'b', 'c']
result = itertools.zip_longest(numbers, letters)
for item in result:
print(item)
# (1, 'a')
# (2, 'b')
# (3, 'c')
# (4, None)
Здесь zip_longest()
продолжает работу до тех пор, пока не достигнет конца самого длинного итератора, заполняя недостающие значения None
.
import itertools
numbers = [1, 2, 3, 4]
letters = ['a', 'b']
result = itertools.zip_longest(numbers, letters, fillvalue='empty')
for item in result:
print(item)
# (1, 'a')
# (2, 'b')
# (3, 'empty')
# (4, 'empty')
Здесь мы заменили значение по умолчанию для fillvalue
на строку 'empty', чтобы указать на отсутствующие элементы.
import itertools
numbers = [1, 2]
chars = ['a', 'b']
flags = [True, False, True]
result = itertools.zip_longest(numbers, chars, flags)
for item in result:
print(item)
# (1, 'a', True)
# (2, 'b', False)
# (None, None, True)
Как видим, zip_longest()
с легкостью справляется с объединением более двух итераторов.
zip_longest()
вместо zip()
: Когда важно убедиться, что ни один элемент из длинных итераторов не будет утерян, zip_longest() будет предпочтительнее. Обычная функция zip()
прекратит выполнение, как только закончится самый короткий итератор.fillvalue
: Осознанно подходите к выбору fillvalue
. Это значение должно отличаться от возможных элементов итератора, чтобы его можно было легко идентифицировать как заполнитель.None
: Если вы не предоставите fillvalue
, будет использован None
. В некоторых случаях это может вызвать путаницу, особенно если None может быть нормальным значением в вашем итераторе.itertools.zip_longest()
- это мощный инструмент для работы с итераторами разной длины, особенно когда важно сохранить все данные из каждого итератора. Однако его следует использовать осознанно, учитывая потребность в заполнителях и возможные последствия выбора fillvalue
.
Эта функция может быть особенно полезна в обработке данных, когда вам нужно работать с несколькими потоками информации одновременно, а также в ситуациях, когда данные могут прийти в несинхронизированных потоках или батчах.
Содержание: