← Назад к вопросам

Как работает zip в Python?

1.3 Junior🔥 241 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает zip() в Python

funkcija zip() — это встроенная функция Python, которая объединяет несколько итерируемых объектов (списки, кортежи, строки и т.д.) и возвращает итератор кортежей. Это одна из самых полезных и часто используемых функций.

Базовый синтаксис и примеры

1. Основное использование

names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]

# zip объединяет списки попарно
zipped = zip(names, ages)
print(list(zipped))
# Результат: [('Alice', 25), ('Bob', 30), ('Charlie', 35)]

2. Различные итерируемые объекты

# Работает со списками, кортежами, строками, диапазонами
letters = ['a', 'b', 'c']
numbers = (1, 2, 3)
result = zip(letters, numbers)
print(list(result))
# [('a', 1), ('b', 2), ('c', 3)]

# Со строками
words = ['hello', 'world']
chars = zip(*words)  # распаковка
print(list(chars))
# [('h', 'w'), ('e', 'o'), ('l', 'r'), ('l', 'd'), ('o', '')]

Как работает zip() внутри

Механизм работы

# zip() — это итератор
zipper = zip([1, 2, 3], ['a', 'b', 'c'])
print(type(zipper))
# <class 'zip object'>

# zip не создаёт список в памяти сразу
# Он генерирует кортежи по одному при итерации
for pair in zip([1, 2, 3], ['a', 'b', 'c']):
    print(pair)
# (1, 'a')
# (2, 'b')
# (3, 'c')

# Это экономит память при работе с большими данными
huges = zip(range(1000000), range(1000000, 2000000))
# Память используется минимально, потому что zip — это ленивый итератор

Внутренняя реализация (упрощённо)

# Это приблизительно как работает zip()
class MyZip:
    def __init__(self, *iterables):
        self.iterables = [iter(it) for it in iterables]
    
    def __iter__(self):
        return self
    
    def __next__(self):
        values = []
        for it in self.iterables:
            try:
                values.append(next(it))
            except StopIteration:
                # Когда хотя бы один итератор кончился, останавливаемся
                raise StopIteration
        return tuple(values)

# Использование:
my_zip = MyZip([1, 2, 3], ['a', 'b', 'c'])
print(list(my_zip))
# [('a', 1), ('b', 2), ('c', 3)]

Поведение при разных длинах

Стандартное поведение: останавливается на самом коротком

short = [1, 2]
long = ['a', 'b', 'c', 'd']

result = zip(short, long)
print(list(result))
# [(1, 'a'), (2, 'b')]
# Остаток ['c', 'd'] игнорируется!

Альтернатива: zip_longest() для заполнения пропусков

from itertools import zip_longest

short = [1, 2]
long = ['a', 'b', 'c', 'd']

# zip_longest заполняет пропуски значением (по умолчанию None)
result = zip_longest(short, long)
print(list(result))
# [(1, 'a'), (2, 'b'), (None, 'c'), (None, 'd')]

# Можно задать своё значение для заполнения
result = zip_longest(short, long, fillvalue=0)
print(list(result))
# [(1, 'a'), (2, 'b'), (0, 'c'), (0, 'd')]

Распаковка с помощью *

Обратная операция: unzip

pairs = [('Alice', 25), ('Bob', 30), ('Charlie', 35)]

# Используем *zip() для распаковки
names, ages = zip(*pairs)
print(names)
# ('Alice', 'Bob', 'Charlie')
print(ages)
# (25, 30, 35)

# Это работает благодаря * который распаковывает список кортежей
# Эквивалентно: zip(('Alice', 25), ('Bob', 30), ('Charlie', 35))

Практический пример: транспонирование матрицы

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# Транспонирование с помощью *zip()
transposed = list(map(list, zip(*matrix)))
print(transposed)
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

# Или просто кортежами
transposed = list(zip(*matrix))
print(transposed)
# [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

Практические примеры

Пример 1: Параллельная обработка нескольких списков

students = ['Alice', 'Bob', 'Charlie']
marks = [85, 92, 78]
attendance = [95, 87, 92]

# Обрабатываем все три списка одновременно
for name, mark, attend in zip(students, marks, attendance):
    if mark >= 80 and attend >= 80:
        print(f"{name}: отличник")
    else:
        print(f"{name}: нужно учиться")

Пример 2: Создание словаря из двух списков

keys = ['a', 'b', 'c']
values = [1, 2, 3]

# Способ 1: через zip
my_dict = dict(zip(keys, values))
print(my_dict)
# {'a': 1, 'b': 2, 'c': 3}

# Способ 2: через dict comprehension
my_dict = {k: v for k, v in zip(keys, values)}
print(my_dict)
# {'a': 1, 'b': 2, 'c': 3}

Пример 3: Группировка данных

data = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# Группируем по 3 элемента
grouped = zip(*[iter(data)] * 3)
print(list(grouped))
# [(1, 2, 3), (4, 5, 6), (7, 8, 9)]

# Это работает потому что *[iter(data)] * 3 создаёт 3 ссылки на один итератор
# каждая из них читает следующие значения

Пример 4: Сравнение двух последовательностей

old_values = [10, 20, 30, 40]
new_values = [10, 25, 30, 45]

# Показываем, что изменилось
for old, new in zip(old_values, new_values):
    if old != new:
        print(f"Изменение: {old} -> {new}")

# Вывод:
# Изменение: 20 -> 25
# Изменение: 40 -> 45

Производительность

zip() vs list comprehension

import timeit

# zip — быстрее и лаконичнее
setup = """
list1 = list(range(1000))
list2 = list(range(1000))
"""

# Способ 1: zip
code1 = "result = list(zip(list1, list2))"
time1 = timeit.timeit(code1, setup, number=10000)

# Способ 2: list comprehension
code2 = "result = [(list1[i], list2[i]) for i in range(len(list1))]"
time2 = timeit.timeit(code2, setup, number=10000)

print(f"zip(): {time1}")
print(f"list comprehension: {time2}")
# zip обычно быстрее на 30-40%

Когда использовать zip

Используй zip когда:

  • Нужно обработать несколько последовательностей параллельно
  • Нужно создать словарь из двух списков
  • Нужно распаковать список кортежей
  • Нужно транспонировать матрицу

НЕ используй zip когда:

  • Индексы важны (используй enumerate)
  • Нужна особая обработка разных длин (используй zip_longest)
  • Изменяешь данные на лету (используй list comprehension с range)

Заключение

zip() — это **мощный инструмент** для работы с несколькими последовательностями одновременно. Это **ленивый итератор**, который экономит память. Помни о разных длинах списков и используй zip_longest если нужно обработать все элементы.
Как работает zip в Python? | PrepBro