Pythonでリストのtranspose

Python には Ruby の Array#transpose に当たるメソッドがない。
で、最初こう書いた。

def transpose(list_of_lists):
    ary = []
    for i in range(len(list_of_lists[0])):
        ary.append(map(lambda x: x[i], list_of_lists))
    return ary

でも、これって内包表記でできそうだよな。と思い直してちょっと悩んで書いたのがこれ。

def transpose(list_of_list):
    return [[x[i] for x in list_of_list] for i in range(len(list_of_list[0]))]

最初のより短くなったけど、二重の内包表記はわかりにくい。もうちょっとわかりやすくはいかないもんだろうか。で、ググってみたら zip と引数展開を使うやり方を見つけた。

 cf. Transpose a matrix in Python – stackoverflow

def transpose(list_of_list):
    return map(list, zip(*list_of_list))

これは分かりやすい。zip の引数に * をつけて渡すことで、引数を展開している。で、このままだとタプルのリストになるので、map を使ってリストのリストに直してるわけだ。

>>> l = [[1,2,3], [4,5,6], [7,8,9]]
>>> zip(*l)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> map(list, zip(*l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]