はじめに
pythonで最もよく使うデータ構造であるリストとタプルですが、この二つの大きな違いは要素の値の変更ができるかどうかです。 リストだと値の変更ができますが、タプルだと変更ができません。 この性質は、ハッシュ化できるかどうかに関係しており、辞書型のキーとして指定できるかに関係しています。 タプルはハッシュ化でき、辞書型のキーとして指定できますが、リストはできません。
リストからタプルへ
私は上に書いたタプルの辞書型のキーとして指定できるという性質を使う為、リストをタプルに変換することがあります。 pythonでリストをタプルに変換する際、次のような書き方があります。
>>> a = [1,2,3,4] >>> tuple(a) (1, 2, 3, 4)
問題点
上で示した変換方法では入れ子構造のリストを、構造を維持したままタプルに変換することができないという問題点があります。 そのまま上の方法を用いると一番浅い階層の部分しかタプルに変換されません。
>>> a = [[1,2],[3,4]] >> tuple(a) ([1, 2], [3, 4])
こうしたい→((1, 2), (3, 4))
入れ子構造のリストからタプルへ
もっといい方法があるかもしれませんが、再帰で実装してしまいましょう!
def list_to_tuple(_list): t = () for e in _list: if isinstance(e,list): t += (list_to_tuple(e),) else: t += (e,) return t if __name__ == '__main__': a = [[1,2],[3,4]] b = list_to_tuple(a) print b
動作確認
>>> list_to_tuple([[1,2],[3,4]]) ((1, 2), (3, 4)) >>> list_to_tuple([1,[2,[3,[4,5]]]]) (1, (2, (3, (4, 5))))
入れ子構造を維持したまま変換できているようです。
おまけ
pythonでハッシュ値を計算する関数にhash()があります。 試しにリストのハッシュを計算してみるとエラーになります。
>>> hash([1,2,3]) Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list'
タプルだと問題なく値が計算できます。
>>> hash((1,2,3)) 2528502973977326415