Объединение итераторов с помощью zip в Python

Раздел: Основы Python -> Встроенные функции

Основы работы с zip

Функция zip() принимает несколько итераторов (списки, кортежи, строки и т.д.) и создаёт итератор, возвращающий кортежи, составленные из соответствующих элементов входных последовательностей. Итерация завершается, когда заканчивается самая короткая последовательность. Это базовый и наиболее частый способ использования.

letters = ['a', 'b', 'c']
numbers = [1, 2, 3]
result = zip(letters, numbers)
print(list(result))

Python max (функция max в python)

[('a', 1), ('b', 2), ('c', 3)]

функция bin python (встроенная функция bin() в python)

Здесь из двух списков создаются пары. Если списки разной длины, лишние элементы игнорируются.

Как объединить последовательности разной длины без потери элементов?

Стандартный zip() обрезает самую длинную последовательность. Для заполнения недостающих элементов используется itertools.zip_longest().

from itertools import zip_longest

a = [1, 2, 3]
b = [10, 20]
result = zip_longest(a, b, fillvalue=0)
print(list(result))

Python id name (использование id() и name в python)

[(1, 10), (2, 20), (3, 0)]

команда open в python (команда open для открытия файлов в python)

Параметр fillvalue задаёт значение для отсутствующих позиций.

Типичная ошибка: забыть импортировать zip_longest или неправильно указать fillvalue. Если не указать fillvalue, используется None, что может привести к ошибкам типа при дальнейшей обработке.

Как создать словарь из двух списков (ключи и значения)?

Передача результата zip() в dict().

keys = ['name', 'age', 'city']
values = ['Alice', 25, 'Moscow']
dictionary = dict(zip(keys, values))
print(dictionary)

Enumerate python (функция enumerate в python)

{'name': 'Alice', 'age': 25, 'city': 'Moscow'}

функция sum в python (функция sum в python)

Этот приём часто применяется при чтении данных из файлов или баз данных.

Проблема: если списки разной длины, словарь будет содержать только количество пар, равное длине более короткого списка. Лишние ключи или значения будут проигнорированы. Это может быть незаметной ошибкой.

Как распаковать (развернуть) список кортежей обратно в отдельные списки?

Используется оператор * вместе с zip().

pairs = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(*pairs)
print(letters)
print(numbers)

функция zip в python (функция zip в python)

('a', 'b', 'c')
(1, 2, 3)

минимальное целое число python (минимальное целое число)

Это работает как обратная операция: zip(*pairs) «разворачивает» кортежи по столбцам.

Как выполнить параллельный перебор нескольких последовательностей в цикле?

Самый простой способ – использовать for с zip().

names = ['Alice', 'Bob', 'Charlie']
scores = [90, 85, 95]
for name, score in zip(names, scores):
    print(f'{name}: {score}')
Alice: 90
Bob: 85
Charlie: 95

При этом не нужно обращаться по индексам.

Распространённая ошибка: изменение одного из итераторов (например, списка) во время итерации в zip может привести к непредсказуемому поведению, так как zip создаёт итератор, а не замороженную копию. Лучше избегать изменений внутри цикла.

Расширенные примеры с zip

Транспонирование матрицы (списка списков)

Используя zip(*matrix) можно «повернуть» матрицу - строки становятся столбцами.

Пример
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
transposed = list(zip(*matrix))
print(transposed)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

Если нужны списки вместо кортежей, можно применить map(list, zip(*matrix)).

Параллельная обработка данных из нескольких файлов или стримов

Предположим, есть три списка: время, температура, давление. Требуется создать список словарей.

Пример
times = ['00:00', '01:00', '02:00']
temps = [20.5, 21.0, 19.8]
pressures = [760, 758, 761]

records = [
    {'time': t, 'temp': tmp, 'pressure': p}
    for t, tmp, p in zip(times, temps, pressures)
]
print(records)
[{'time': '00:00', 'temp': 20.5, 'pressure': 760}, {'time': '01:00', 'temp': 21.0, 'pressure': 758}, {'time': '02:00', 'temp': 19.8, 'pressure': 761}]

Использование zip с генераторами

Генераторы тоже можно передавать в zip(). Важно помнить, что генераторы являются однократными итераторами.

Пример
def squares(n):
    for i in range(n):
        yield i ** 2

def cubes(n):
    for i in range(n):
        yield i ** 3

result = list(zip(squares(4), cubes(4)))
print(result)
[(0, 0), (1, 1), (4, 8), (9, 27)]

При завершении одного из генераторов zip остановится.

Объединение неограниченного количества итераторов с zip_longest

Передача переменного числа итераторов и заполнение пропусков.

Пример
from itertools import zip_longest

data1 = [10, 20, 30]
data2 = [1, 2]
data3 = [100, 200, 300, 400]

result = list(zip_longest(data1, data2, data3, fillvalue='N/A'))
print(result)
[(10, 1, 100), (20, 2, 200), (30, 'N/A', 300), ('N/A', 'N/A', 400)]

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

Строка также является итератором.

Пример
string = 'ABC'
numbers = [1, 2, 3]
pairs = list(zip(string, numbers))
print(pairs)
[('A', 1), ('B', 2), ('C', 3)]

При разной длине будет обрезано до короткого.

Использование zip для сравнения двух последовательностей поэлементно

Пример
list1 = [1, 2, 3, 4]
list2 = [1, 2, 0, 4]
diff = [a - b for a, b in zip(list1, list2)]
print(diff)
[0, 0, 3, 0]

Так можно находить расхождения.

Функция zip в Python - comments

En
функция zip в python (python)