おっぱいそん!

pythonを数値計算に使うときのテクニックとかをまとめていきたい。

Named tuple

pythonの組み込みのコンテナ型(=コレクション型)にはリスト、タプル、ディクショナリがある。
この記事では、名前付きタプルというコンテナ型を紹介したい。(名前つきタプルはクラスの書き方をふんだんに使っているので、クラスを知らない人はクラスを先に勉強した方がいいと思います。この記事でもクラスの基本的なことは前提知識としています。)
名前付きタプルはタプルの子クラスで、インデックスだけでなく、クラスのように変数名(ドット表記)でも要素にアクセスできるコンテナ型です

使用例

例えば、以下のように使用できる。

from collections import namedtuple
from math import sqrt

Vector = namedtuple('Vector', 'x, y')
vec1 = Vector(x=1.0, y=5.0)
vec2 = Vector(2.5, 1.5)
distance = sqrt((vec1.x-vec2.x)**2 + (vec1.y-vec2.y)**2)
print "distance =", distance

使用するには、collectionsからimportする必要がある。
namedtuple()はクラスを作る関数で、引数はクラス名(慣習として、クラス名は大文字で始める)、要素(インスタンス変数)の名前。
要素の名前の部分は、'x y'や['x', 'y']のように書いてもよい。
また、要素の呼び出しはsqrt((vec1[0]-vec2[0])**2 + (vec1[1]-vec2[1])**2)と、普通のタプルのようにインデックスでも出来る。

長所

いいところ:

  • タプルより要素の取り出しが分かりやすい(ドットを使ったオブジェクト的な書き方が出来る)。
  • 辞書より高速でメモリが節約できる(メモリの使用量は普通のタプルと同じ)。

わるいところ:

  • import correctionがいる。

普通のタプルのような使い方もできるので、元々、普通タプルで書いていたコードを書き換えずにnamed tupleに、一部だけをnamed tupleにすることも出来ます。

メソッド

タプルのメソッドの他に幾つかの新たなメソッドが定義されているが、要素名との衝突を避けるために、アンダースコアから始まる。

Vector = namedtuple('Vector', ['x', 'y'])
vec1 = Vector(x=1.0, y=5.0)
print vec1
print vec1._fields
vec1 = vec1._replace(x=4.)
print vec1

_fieldsは要素の名前を取得するメソッドで、replaceは値を書き換えるメソッド(タプルなので、普通に書き換えようとするとエラーがでる)。
他のメソッドは以下のリンクを参照。
http://docs.python.jp/2/library/collections.html#collections.namedtuple

比較

最後に、tuple, dict, classとの比較をしておく(正確にはtupleもdictもクラスだが)。
以下をみれば分かるように、クラスの書き方に近い。

from collections import namedtuple
from math import sqrt

Vector_tuple = namedtuple('Vector_tuple', 'x, y')
vec = Vector_tuple(x=1., y=2.)
print vec[0], vec.x

vec_tuple = (1., 2.)
print vec_tuple[0]

vec_dict = {'x':1., 'y':2.}
print vec_dict['x']

class Vector_class:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def distance(self):
        print sqrt((self.x)**2 + (self.y)**2)
vec_class = Vector_class(x=1., y=2.)
print vec_class.x
vec_class.distance()

http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python
http://mtwtkman.com/blog/20150203232818/python%E3%81%AEcollections%E3%82%84%E3%81%B0%E3%81%84%28namedtuple%E3%81%AE%E5%A0%B4%E5%90%88%29
http://labs.triax.jp/python-2-4-advent-calendar-namedtuple
http://xaro.hatenablog.jp/entry/2015/07/11/024200