This is a smart bit. Here's a breakdown:
[::-1] - makes a shallow copy of the original list in reverse order. You can also use reversed() , which will lead to a reverse iterator over the list, rather than actually copying the list (a more efficient amount of memory).* - makes each subscription in the source list a separate argument to zip() (i.e. unpacks the list)zip() - transfers one element from each argument and displays a list (well, a tuple) of them and repeats until all the sublists have been exhausted. This is where the transfer actually takes place.
So, suppose you have this:
[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
First you get this (shallow, reverse copy):
[ [7, 8, 9], [4, 5, 6], [1, 2, 3] ]
Then each of the subscriptions is passed as a zip argument:
zip([7, 8, 9], [4, 5, 6], [1, 2, 3])
zip() repeatedly consumes one element from the beginning of each of its arguments and makes a tuple from it until there are more elements, resulting in:
[(7, 4, 1), (8, 5, 2), (9, 6, 3)]
And Bob is your uncle.
To answer the @IkeMiguel question in the comment about rotating it in the other direction, this is pretty simple: you just need to undo both sequences that go into the zip and the result. The first can be achieved by removing [::-1] , and the second can be achieved by throwing reversed() around everything. Since reversed() returns an iterator over the list, we will need to put list() around it to convert it. So:
rotated = list(zip(*reversed(original)))
Of course, you can also just rotate the list clockwise three times. :-)