zip – встроенная функция python для работы с итерируемыми объектами. Ее суть состоит в том, чтобы на каждой итерации брать очередной элемент каждого из итерируемых объектов и объединять их в кортеж.
Рассмотрим пример:
a = [1, 2, 3]
b = [4, 5, 6, 7]
print(*zip(a, b))
После выполнения кода мы получим
(1, 4) (2, 5) (3, 6)
Легко заметить, что zip() сгруппировала соответствующие элементы в кортежи. Первый элемент первой последовательности с первым элементом второй, второй со вторым и так далее, пока не закончилась кратчайшая последовательность.
А что будет если дать на вход список списков, предварительно его распаковав?
a = [[1, 2, 3],
[4, 5, 6]]
print(list(zip(*a)))
Получим
(1, 4) (2, 5) (3, 6)
Обратите внимание, что фактически мы транспонировали (отразили) матрицу и ее строки стали столбцами. Единственная проблема – строки стали неизменяемыми, но эту проблему легко исправить с помощью функции map().
a = [[1, 2, 3], [4, 5, 6]]
a = list(map(list, zip(*a)))
print(a)
[[1, 4], [2, 5], [3, 6]]
Когда это может быть полезно?
Например в задачах про числовой прямоугольник и числовую змейку. Достаточно построить квадрат и змейку по алгоритмам из первых версий заданий, после чего просто транспонировать наши матрицы. Главное не забыть поменять местами высоту и ширину, ведь эти переменные тоже поменяются местами.
Еще более интересных результатов можно добиться если скомбинировать zip() со срезом [::-1].
a = [[1, 2, 3], [4, 5, 6]]
a = list(map(list, list(zip(*a))[::-1]))
print(a)
[[3, 6], [2, 5], [1, 4]]
или
a = [[1, 2, 3], [4, 5, 6]]
a = list(map(list, zip(*a[::-1])))
print(a)
[[4, 1], [5, 2], [6, 3]]
Эти нехитрые задачи позволяют просто “вертеть” матрицы, для того, чтобы использовать более простые алгоритмы при их заполнении или обработке.
я правильно понимаю что * перед zip лишняя??
во втором блоке кода
совершенно верно.