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]]