Неочевидное использование zip()

zip – встроенная функция python для работы с итерируемыми объектами. Ее суть состоит в том, чтобы на каждой итерации брать очередной элемент каждого из итерируемых объектов и объединять их в кортеж.

Рассмотрим пример:

Python
a = [1, 2, 3]
b = [4, 5, 6, 7]

print(*zip(a, b))

После выполнения кода мы получим

(1, 4) (2, 5) (3, 6)

Легко заметить, что zip() сгруппировала соответствующие элементы в кортежи. Первый элемент первой последовательности с первым элементом второй, второй со вторым и так далее, пока не закончилась кратчайшая последовательность.

А что будет если дать на вход список списков, предварительно его распаковав?

Python
a = [[1, 2, 3], 
     [4, 5, 6]]

print(list(zip(*a)))

Получим

(1, 4) (2, 5) (3, 6)

Обратите внимание, что фактически мы транспонировали (отразили) матрицу и ее строки стали столбцами. Единственная проблема – строки стали неизменяемыми, но эту проблему легко исправить с помощью функции map().

Python
a = [[1, 2, 3], [4, 5, 6]]

a = list(map(list, zip(*a)))

print(a)
[[1, 4], [2, 5], [3, 6]]

Когда это может быть полезно?
Например в задачах про числовой прямоугольник и числовую змейку. Достаточно построить квадрат и змейку по алгоритмам из первых версий заданий, после чего просто транспонировать наши матрицы. Главное не забыть поменять местами высоту и ширину, ведь эти переменные тоже поменяются местами.

Еще более интересных результатов можно добиться если скомбинировать zip() со срезом [::-1].

Python
a = [[1, 2, 3], [4, 5, 6]]

a = list(map(list, list(zip(*a))[::-1]))

print(a)
[[3, 6], [2, 5], [1, 4]]

или

Python
a = [[1, 2, 3], [4, 5, 6]]

a = list(map(list, zip(*a[::-1])))

print(a)
[[4, 1], [5, 2], [6, 3]]

Эти нехитрые задачи позволяют просто “вертеть” матрицы, для того, чтобы использовать более простые алгоритмы при их заполнении или обработке.

Подписаться
Уведомить о
guest
2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
nmalkam
03.01.2024 12:22
print(list(*zip(*a)))

я правильно понимаю что * перед zip лишняя??

во втором блоке кода