2021年9月21日火曜日

【リスト】二次元リストの行と列の転置

 二次元リストの行と列を直接転置する関数やメソッドはないためリスト内包表記を使うか、*演算子によるリストのアンパックとzipを組み合わせて使う。


1. リスト内包表記による二次元リストの行と列の転置

 二重にしたリスト内包表記で二次元リストの各行の1番目、2番目・・・の要素を取り出してリスト化できる。
[row for row in matrix] は各行への展開で、row[i]としてインデックスがついているので後半の[for i in range(4)]によりrow[1],row[2]・・・つまり各行の1番目,2番目・・・の要素を指定している。

matrix = [[1, 2, 3, 4],
          [5, 6, 7, 8],
          [9, 10, 11, 12]]

print([[row[i] for row in matrix] for i in range(4)])

実行結果

[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]


2. *,zipによる二次元リストの行と列の転置

 *演算子は展開(アンパック)に用いられ、ここでは二次元リストを各行([1, 2, 3, 4] [5, 6, ・・] [7, ・・・・])に展開している。zipは要素の組み合わせを作る(例えば zip('ABCD', 'xy') --> Ax By)ので、*で各行に展開し、zipで各行の要素の組み合わせを作る。
zipはイテレータを返すのでlistでリストに変換するが、zip自体はタプルを返す、つまり(1, 5, 9)といったタプルのリストができるので、さらにリスト内包表記でタプルを一つずつ取り出してlistによりリスト化する。

matrix = [[1, 2, 3, 4],
          [5, 6, 7, 8],
          [9, 10, 11, 12]]

print([list(i) for i in list(zip(*matrix))])

実行結果

[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]


3. リファレンス

Python チュートリアル > 5. データ構造 > 5.1.4. ネストしたリストの内包表記
Python チュートリアル > 4. その他の制御フローツール > 4.7.5. 引数リストのアンパック
Python 標準ライブラリ > 組み込み関数 > zip(*iterables)

使用バージョン:Python 3.8.8

0 件のコメント:

コメントを投稿