Это умный бит.Вот разбивка:
[::-1]
- делает мелкую копию оригинального списка в обратном порядке.Можно также использовать reversed()
, который будет производить обратный итератор по списку, а не копировать его фактически (более эффективно использовать память). *
- делает каждый подсписок в исходном списке отдельным аргументом для zip()
(то есть распаковывает список) zip()
- берет один элемент из каждого аргумента и составляет список (ну, кортеж) из них и повторяет до тех пор, пока не исчерпаны все подсписки.Вот где в действительности происходит транспонирование.
Итак, предположим, что у вас есть это:
[ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
Сначала вы получите это (мелкая, перевернутая копия):
[ [7, 8, 9],
[4, 5, 6],
[1, 2, 3] ]
Далее каждый из подсписков передается в качестве аргумента zip
:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip()
многократно потребляет один элемент в начале каждого из своих аргументов и делает из него кортеж до тех пор, покабольше нет предметов, в результате чего:
[(7, 4, 1),
(8, 5, 2),
(9, 6, 3)]
И Боб - твой дядя.
Чтобы ответить на вопрос @ IkeMiguel в комментарии о его вращении в другом направлении, это довольно просто: вы простонужно поменять обе последовательности, которые входят в zip
, и результат.Первое может быть достигнуто путем удаления [::-1]
, а второе - путем разбрасывания reversed()
вокруг всего объекта.Так как reversed()
возвращает итератор по списку, нам нужно поместить list()
вокруг , что , чтобы преобразовать его.Итак:
rotated = list(zip(*reversed(original)))
Конечно, вы также можете просто повернуть список по часовой стрелке три раза.: -)