【collections.namedtuple】Pythonでタプルに名前をつける方法
本記事は、collections.namedtuple
の基本的な使い方を解説しています。引数やメソッドなどの特徴を説明するためのコード例を作成しています。それらを参考にしながらnamedtuple
を使いこなせるようになりましょう。
本記事は、こちらのドキュメントを参考にしているため、pythonのバージョンによっては挙動が異なる場合があります。その場合は、ドキュメントを参照してください。
collectionsには、他にどんな関数があるのか気になる方は、こちらの記事にまとめています。
namedtupleとは
namedtuple
は、Pythonのcollections
モジュールに含まれるデータ型です。
この collections.namedtuple
は次のような特徴があります。
- タプルに名前を付けることができるので、タプルの中身がわかりやすくコードの可読性が上がる
namedtuple
は、イミュータブルなデータ型なので、いつの間にか値を変更してしまっていたというような事故を防げる
今回は、このような特徴があるcollections.namedtuple
の引数について具体的な使用例を交えて解説します。
また、collections.namedtuple
の3つの追加メソッドと2つの属性についても見ていきます。
collections.namedtupleの引数
collections — namedtuple コンテナデータ型 — Python 3.11.0b5 ドキュメント
collections.namedtuple
の引数の簡単な説明は以下になります。
typename
: 生成するタプルの名前を文字列で指定します。field_names
: タプルに含めるフィールド名を文字列または文字列のイテレータで指定します。複数のフィールド名を指定する場合は、スペースで区切ります。rename
: フィールド名を小文字に変換して、同じフィールド名が複数ある場合に区別する場合は、True
を指定します。デフォルトはFalse
です。defaults
: 生成するタプルに初期値を指定するためのタプルを指定します。初期値を指定する場合は、フィールドの数と同じ数の値を指定する必要があります。module
: 生成するタプルを属するモジュールを文字列で指定します。デフォルトはNone
です。
では、それぞれ具体例を用いて使い方を見ていきましょう。
typename
typename
引数は、生成するnamedtuple
の型の名前を文字列で指定します。
・typename
を指定することで、生成されるnamedtuple
のインスタンスをよりわかりやすくすることができます。
・複数のnamedtuple
を使用する場合、typename
を指定することで、どのnamedtuple
のインスタンスであるかをわかりやすくすることができます。
以下は、typename
引数を使用した例です。
from collections import namedtuple
# typename引数を使用する
Point = namedtuple('Point', ['x', 'y'])
# namedtupleを使用する
p = Point(x=1, y=2)
print(p) # Output: Point(x=1, y=2)
field_names
field_names
引数は、生成するnamedtuple
に含めるフィールド名を文字列または文字列のイテレータで指定します。
ちなみに、後述のメソッド名や属性名がアンダースコア( _ )から始まるので、同じようにアンダースコアから始めるとValueError: Field names cannot start with an underscore: '_'
というエラーがでます。
以下は、field_names
引数を使用した例です。
from collections import namedtuple
# field_names引数を使用する
Person = namedtuple('Person', 'name')
# namedtupleを使用する
p = Person(name='John')
print(p) # Output: Person(name='John')
複数のフィールド名を指定する場合は、以下のような記述方法があります。
from collections import namedtuple
# field_names引数を使用する
Person1 = namedtuple('Person1', ['name', 'age'])
Person2 = namedtuple('Person2', ('name', 'age'))
Person3 = namedtuple('Person3', ('name age'))
Person4 = namedtuple('Person3', ('name, age'))
# namedtupleを使用する
p1 = Person1(name='John', age=30)
p2 = Person2(name='John', age=30)
p3 = Person3(name='John', age=30)
p4 = Person4(name='John', age=30)
print(p1) # Output: Person(name='John', age=30)
print(p2) # Output: Person(name='John', age=30)
print(p3) # Output: Person(name='John', age=30)
print(p4) # Output: Person(name='John', age=30)
どの記述方法でも複数のフィールド名を指定できます。
複数のフィールド名を指定する方法
・リストにフィールド名を格納
・タプルにフィールド名を格納
・空白で区切る
・コンマで区切る
ちなみに、大文字と小文字は区別するので、異なるフィールド名として扱われます。
from collections import namedtuple
# namedtuple を作成
Person = namedtuple('Person', 'name Name', defaults=(0, 0))
# Person オブジェクトを作成
p = Person(name='Alice')
print(p) # Person(name='Alice', Name=0)
rename
rename
引数は、フィールド名を小文字に変換して、同じフィールド名が複数ある場合に区別する場合にTrueを指定します。デフォルトはFalse
です。
rename=True
の場合
以下は、rename=True
の場合です。
from collections import namedtuple
# `rename=True` を指定して namedtuple を作成
Person = namedtuple('Person', 'name age age', defaults=(0, 0), rename=True)
# 名前と年齢が同じフィールドを持つ Person オブジェクトを作成
p = Person(name='Alice', age='30')
print(p) # Person(name='Alice', age='30', _2=0)
上記の例では、age
がフィールドに二つあるので、二つ目のage
が位置を示す_2
に置き換わっています。
また、defのような予約語についても置き換えられます。
from collections import namedtuple
# `rename=True` を指定して namedtuple を作成
Person = namedtuple('Person', 'name age def', defaults=(0, 0), rename=True)
# Person オブジェクトを作成
p = Person(name='Alice', age='30')
print(p) # Person(name='Alice', age='30', _2=0)
rename=True
の場合
同じ名前のフィールド名や予約語と同じフィールド名などは、位置を示す文字に置き換えられる。
rename=False
の場合
以下は、rename=False
の場合、つまりデフォルトの場合に同じフィールド名を指定してみます。
from collections import namedtuple
# `rename=True` を指定して namedtuple を作成
Person = namedtuple('Person', 'name age age', defaults=(0, 0))
# 名前と年齢が同じフィールドを持つ Person オブジェクトを作成
p = Person(name='Alice')
print(p) # ValueError: Encountered duplicate field name: 'age'
rename=False
の場合
同じ名前のフィールド名や予約語と同じフィールド名を設定すると、エラーが出てしまう。
defaults
defaults
: 生成するタプルに初期値を指定するためのタプルを指定します。
from collections import namedtuple
# フィールドに初期値を指定するように、タプルを定義します
Person = namedtuple('Person', 'name age height', defaults=(0, 0, 1))
# Person タプルを生成します
p = Person('Alice')
# Person タプルのフィールドにアクセスするには、属性名を使用します
print(p.name) # Alice
print(p.age) # 0 (初期値)
print(p.height) # 1 (初期値)
上記の例では、defaults
で(0, 0, 1)
と指定してageとheightの初期値を指定しています。
また、フィールドの数より一つ少なくしても初期値を設定できます。
from collections import namedtuple
# フィールドに初期値を指定するように、タプルを定義します
Person = namedtuple('Person', 'name age height', defaults=(1, 6))
# Person タプルを生成します
p = Person('Alice')
# Person タプルのフィールドにアクセスするには、属性名を使用します
print(p.name) # Alice
print(p.age) # 1 (初期値)
print(p.height) # 6 (初期値)
この場合は、フィールドの始めに定義したnameにはdefaults
は考慮されず、次のageから初期値が入れられています。
もちろん、タプルを生成時にageやheightを設定すると、その設定が優先されます。
from collections import namedtuple
# フィールドに初期値を指定するように、タプルを定義します
Person = namedtuple('Person', 'name age height', defaults=(1, 6))
# Person タプルを生成します
p = Person('Alice', 22, 150)
# Person タプルのフィールドにアクセスするには、属性名を使用します
print(p.name) # Alice
print(p.age) # 22
print(p.height) # 150
module
module
: 生成するタプルを属するモジュールを文字列で指定します。デフォルトは None
です。
from collections import namedtuple
# `module` 引数を指定して namedtuple を作成
Person = namedtuple('Person', 'name age gender', module='mymodule')
# Person オブジェクトを作成
p = Person(name='Alice', age='30', gender='female')
print(p) # mymodule.Person(name='Alice', age='30', gender='female')
print(p.__module__) # mymodule
module
引数を指定すると、生成される名前付きタプルクラスの __module__
属性が、指定された値に設定されます。
3つの追加メソッド
namedtuple
には、以下のような3つの特殊メソッドがあります。
_make
_asdict
_replace
これらのメソッドを使うことで、namedtuple
をより便利に操作することができます。
_make
_make
メソッドは、長さが同じであるタプルやイテラブルなオブジェクトから、同じ型のnamedtuple
を作成することができます。
from collections import namedtuple
# namedtupleを使って、x座標とy座標を保持するPoint型を定義
Point = namedtuple('Point', ['x', 'y'])
# タプルを渡して、Point型のnamedtupleを作成
t = (1, 2)
p = Point._make(t)
# Point型のnamedtupleを表示
print(p) # Point(x=1, y=2)
_asdict
_asdict
メソッドは、namedtuple
を辞書型に変換することができます。
from collections import namedtuple
# namedtupleを使って、x座標とy座標を保持するPoint型を定義
Point = namedtuple('Point', ['x', 'y'])
# Point型のnamedtupleを作成
p = Point(1, 2)
# namedtupleを辞書型に変換して表示
d = p._asdict()
print(d) # {'x': 1, 'y': 2}
_replace
_replace
メソッドは、namedtuple
のいくつかのフィールドを置き換えることができます。
from collections import namedtuple
# namedtupleを使って、x座標とy座標を保持するPoint型を定義
Point = namedtuple('Point', ['x', 'y'])
# Point型のnamedtupleを作成
p = Point(1, 2)
# x座標を置き換えて、新しいPoint型のnamedtupleを作成
p2 = p._replace(x=3)
# 新しいPoint型のnamedtupleを表示
print(p2) # Point(x=3, y=2)
2つの属性
namedtuple
には、以下の2つの特殊属性があります。
_fields
_field_defaults
_fields
namedtuple
のフィールド名を保持するタプルを表示できます。
from collections import namedtuple
# namedtupleを使って、x座標とy座標を保持するPoint型を定義
Point = namedtuple('Point', ['x', 'y', 'z'], defaults=[0, 0, 0])
# _fields属性を使ってフィールド名を取得
print(Point._fields) # ('x', 'y', 'z')
_field_defaults
namedtuple
のフィールドに対するデフォルト値を保持する辞書型を表示できます。
from collections import namedtuple
# namedtupleを使って、x座標とy座標を保持するPoint型を定義
Point = namedtuple('Point', ['x', 'y', 'z'], defaults=[0, 0, 0])
# _field_defaults属性を使ってデフォルト値を取得
print(Point._field_defaults) # {'x': 0, 'y': 0, 'z': 0}
まとめ
今回は、namedtuple
の引数などを中心にまとめてみました。
pythonには便利なコンテナがあるということを頭の隅に置いておくことで、何かしらの時に役に立つかもしれません。そんな時に、この記事を思い出していただければ幸いです。
コメント