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

lengthのもうひとつの実装

リストの個数を返す手続き。

 cf. lengthの別の実装 – 理想のユーザ・インターフェイスを求めて

名前付きletの使い方を忘れてて調べた^^;

(define length
  (lambda (l)
    (let loop ((len 0) (lis l))
      (if (null? lis)
          len
          (loop (+ len 1) (cdr lis))))))

(print (length '(1 2 3 4 5)))
takatoh@nightschool $ gosh length.scm
5