読者です 読者をやめる 読者になる 読者になる

ポーカー、プログラミング、もぐ

ポーカーとプログラミングともぐもぐについてのブログ。

Python Numpy無しで転置行列を作る

data = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [0, 1, 2]
]

これを

data = [
    [1, 4, 7, 0],
    [2, 5, 8, 1], 
    [3, 6, 9, 2]
]

こうしたい時。

結論から書くと

list(map(list, zip(*data)))

これでOK。


まず、zip関数は

それぞれのイテラブルから要素を集めたイテレータを作ります。

この関数はタプルのイテレータを返し、その i 番目のタプルは引数シーケンスまたはイテラブルそれぞれの i 番目の要素を含みます。このイテレータは、入力のイテラブルの中で最短のものが尽きたときに止まります。単一のイテラブル引数が与えられたときは、 1-タプルのイテレータを返します。引数がなければ、空のイテレータを返します。次と等価です:

ドキュメントより)

つまり、

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)
"""
zipped = [(1, 4), (2, 5), (3, 6)]
"""

となる。ただし、zip関数が返すのはイテレータのため、リストとして扱いたいときにはlist関数を使う必要がある。

また、イテラブルオブジェクトである引数の先頭に*をつけて指定すると、
引数は呼び出しの時に展開されて渡される。
なので、

zip(*data)

は、

zip([1, 2, 3], [4, 5, 6], [7, 8, 9], [0, 1, 2])

と同じ。
なので、

zipped = zip(*data)
list(zipped)
"""
zipped = [
    (1, 4, 7, 0),
    (2, 5, 8, 1), 
    (3, 6, 9, 2)
]
"""

となる。
ただ、各要素はタプルなので、それぞれをリストにしたい場合は、
map関数を使い、各要素をlistへ変換する。
これを組み合わせると、

list(map(list, zip(*data)))

という書き方で転置行列ができるということになる。