行列を回転させる Pythonic な方法を探しているときに、この回答に出会いました。しかし、それに付随する説明はありません。ここにスニペットをコピーしました:
rotated = zip(*original[::-1])
それはどのように機能しますか?
Ashwini と HennyH による説明を補足するために、プロセスを説明する小さな図を示します。
[::-1]
スライス演算子は list のリストを反転し、リスト全体を取り (したがって、最初の 2 つの引数は省略できます)、 のステップを使用し-1
ます。zip
関数は多数のリストを受け取り、行と列が逆になった新しいリストを効果的に返します。は*
、リストのリストがいくつかのリストにアンパックされていると言います。ご覧のとおり、これら 2 つの操作を組み合わせると、行列が回転します。
>>> lis = [[1,2,3], [4,5,6], [7,8,9]]
[::-1]
リストを反転します:
>>> rev = lis[::-1]
>>> rev
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]
zip
ここで、rev のすべてのアイテムで使用し、返された各タプルをローテーションに追加します。
>>> rotated = []
>>> for item in zip(rev[0],rev[1],rev[2]):
... rotated.append(item)
...
>>> rotated
[(7, 4, 1), (8, 5, 2), (9, 6, 3)]
zip
渡された iterable のそれぞれから同じインデックスから項目を選択し (最小の長さの項目までのみ実行されます)、それらをタプルとして返します。
とは*
:
*
rev
toのすべてのアイテムをアンパックするために使用されるためzip
、手動で入力する代わりに、
rev[0], rev[1], rev[2]
単純に を実行できますzip(*rev)
。
上記のzip
ループは、次のように書くこともできます。
>>> rev = [[7, 8, 9], [4, 5, 6], [1, 2, 3]]
>>> min_length = min(len(x) for x in rev) # find the min length among all items
>>> rotated = []
for i in xrange(min_length):
items = tuple(x[i] for x in rev) # collect items on the same index from each
# list inside `rev`
rotated.append(items)
...
>>> rotated
[(7, 4, 1), (8, 5, 2), (9, 6, 3)]