Python zip strict: ошибка при разной длине

Категория: Python · Язык: Python · Обновлено:

Параметр strict=True у zip() появился в Python 3.10 и заставляет функцию выбросить ValueError, если длины итерируемых объектов различаются. Без него zip молча останавливается на самом коротком, и часть данных теряется. Это особенно опасно при сборке строк из заголовков и значений.

Поймать несовпадение длины

Python
names = ["Анна", "Игорь", "Ольга"]
scores = [90, 85]

print(list(zip(names, scores)))  # [('Анна', 90), ('Игорь', 85)]

try:
    list(zip(names, scores, strict=True))
except ValueError as exc:
    print(exc)  # zip() argument 2 is shorter than argument 1

Обычный zip обрезает результат до двух пар и не сообщает об ошибке. Со strict=True проверка выполняется после исчерпания самого короткого итератора; если длины совпали, поведение не меняется. Сообщение указывает, какой аргумент короче.

Убедиться, что данные полные

Python
pairs = list(zip([1, 2], [3, 4], strict=True))
print(pairs)  # [(1, 3), (2, 4)]

Используйте strict=True при разборе CSV, сравнении конфигураций и любых парных данных, где пропуск строки — ошибка. Если разная длина допустима, оставьте обычный zip или возьмите itertools.zip_longest с явным fillvalue. Смешивать эти стратегии в одном месте не стоит: читатель должен понимать, что произойдёт с лишними значениями.

strict не спасает от бесконечного итератора: zip(count(), [1, 2], strict=True) не завершится, потому что короткий итератор исчерпается, но внешний останется бесконечным. Ограничивайте источник через islice. Параметр работает только в Python 3.10+; на 3.9 и раньше проверяйте длины вручную или используйте zip_longest.

Не оборачивайте zip(strict=True) в try/except ValueError без необходимости: ошибка обычно означает баг в данных, и её лучше не глотать. Если ошибка ожидаема, верните понятное сообщение с номерами строк, а не просто Traceback.

Документация: zip, itertools.zip_longest.