8

行列を回転させる Pythonic な方法を探しているときに、この回答に出会いました。しかし、それに付随する説明はありません。ここにスニペットをコピーしました:

rotated = zip(*original[::-1])

それはどのように機能しますか?

4

3 に答える 3

5

Ashwini と HennyH による説明を補足するために、プロセスを説明する小さな図を示します。

ここに画像の説明を入力

  1. 最初に、[::-1]スライス演算子は list のリストを反転し、リスト全体を取り (したがって、最初の 2 つの引数は省略できます)、 のステップを使用し-1ます。
  2. 次に、このzip関数は多数のリストを受け取り、行と列が逆になった新しいリストを効果的に返します。は*、リストのリストがいくつかのリストにアンパックされていると言います。

ご覧のとおり、これら 2 つの操作を組み合わせると、行列が回転します。

于 2013-06-18T09:29:23.857 に答える
5
>>> 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 のそれぞれから同じインデックスから項目を選択し (最小の長さの項目までのみ実行されます)、それらをタプルとして返します。

とは*:

*revtoのすべてのアイテムをアンパックするために使用されるため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)]
于 2013-06-18T08:53:28.763 に答える