【Python】defaultdictで規定値を持つ辞書を定義する(collections.defaultdict)
.jpg)
Python で規定値を持つ辞書を定義する collections モジュールの defaultdict について解説します。
目次
defaultdict(collections モジュール)
Python 標準の辞書(dict)では、辞書にないキーの値を操作しようとするとエラーになるため、初期化を意識する必要があります。この時、collections モジュールの defaultdict を使用することで規定値を持つ辞書を扱うことができます。
この記事では、規定値を持つ辞書を定義する collections モジュールの defaultdict について基本的な使い方を紹介します。
リスト要素の出現回数カウント
まずは、Python 標準の辞書(dict)を用いてリストに含まれている値の出現数をカウントするプログラムを考えてみます。リストに含まれる値を辞書の key として、カウントを 1 ずつインクリメントしていきます。
例えば、以下のようにプログラムを書いたとします。
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
dict_count = {}
for key in data:
dict_count[key] += 1
print(dict_count)【実行結果例】 Traceback (most recent call last): ...(省略)... KeyError: 'A'
上記プログラムで、"A" は最初は辞書内にないために KeyError が発生します。解決方法として、初期化として値 1 を入れるように設定する方法が使えます。
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
dict_count = {}
for key in data:
if key in dict_count:
dict_count[key] += 1
else:
dict_count[key] = 1
print(dict_count)【実行結果】
{'A': 3, 'B': 3, 'C': 1, 'D': 2}このように対応することが可能ですが、if...else... により少しコードが長くなってしまいます。辞書にないキーの場合は、デフォルトで値に 0 が入るようにできれば、回数をインクリメントする「dict_count[key] += 1」のコードのみでよくなります。
このようなときに簡単に対応できるよう、規定値を持つ辞書を定義できるのが collections モジュールの defaultdict です。
collections.defaultdict の定義と使い方
上記で紹介したリスト要素の出現回数をカウントするプログラムを用いて collections モジュールの defaultdict を使い方を紹介します。
int の 0 で初期化する場合
キーが存在しない場合に値を 0 で規定値として初期化したい場合には、以下のように defaultdict の引数に「int」クラスを指定して使用します。
import collections
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
dict_count = collections.defaultdict(int)
for key in data:
dict_count[key] += 1
print(dict_count)【実行結果】
defaultdict(<class 'int'>, {'A': 3, 'B': 3, 'C': 1, 'D': 2})defaultdict を使用するためには collections モジュールをインポートする必要があります。結果を見るとデフォルトで 0 が設定されるため、リスト要素の出現回数をカウントできていることが分かります。
lambda 関数での表現
上記例では、int クラスを指定しましたが lamda 関数を使用して以下のように記載しても結果は同じになります。
import collections
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
# lambda関数で記載
dict_count = collections.defaultdict(lambda: int())
for key in data:
dict_count[key] += 1
print(dict_count)【実行結果】
defaultdict(<function <lambda> at 0x0000028AC65D6310>, {'A': 3, 'B': 3, 'C': 1, 'D': 2})上記は int() を返却値とする lambda 関数を defaultdict に渡しています。「int()」は print してみると分かりますが 0 になるので、0 で初期化されることになります。結果は同じですが、defaultdict を print してみると先ほどは <class 'int'> となっていたものが function<lambda> となっている点で異なります。
float の 0.0 で初期化する場合
float の 0.0 で規定値を設定する場合も int の時と同様ですが見てみましょう。
import collections
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
dict_count = collections.defaultdict(float)
for key in data:
dict_count[key] += 1.0
print(dict_count)【実行結果】
defaultdict(<class 'float'>, {'A': 3.0, 'B': 3.0, 'C': 1.0, 'D': 2.0})上記を見るとデフォルトで 0.0 が設定されて、1.0 ずつインクリメントできていることが分かります。
lambda 関数での表現
上記例では、float クラスを指定しましたが lamda 関数を使用して以下のように記載しても結果は同じになります。
import collections
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
# lambdaで記載
dict_count = collections.defaultdict(lambda: float())
for key in data:
dict_count[key] += 1.0
print(dict_count)【実行結果】
defaultdict(<function <lambda> at 0x000001AA0507A050>, {'A': 3.0, 'B': 3.0, 'C': 1.0, 'D': 2.0})結果は同じですが、クラスが関数に変わるという点については int() で説明した例と同様になります。
list 等でも同様に対応可能
上記では例として 0 で規定値を設定する int と、0.0 で規定値を設定する float の例を紹介しましたが、以下のような他のクラスも同様に使用可能です。
| クラス | 規定値 |
|---|---|
int | 0 |
float | 0.0 |
list | [] |
dict | {} |
bool | False |
関数で任意の規定値を定義する
lambda 関数のことが理解できると int や float の例が「dict_count = collections.defaultdict(lambda: 0)」や「dict_count = collections.defaultdict(lambda: 0.0)」としても同じことが分かると思います。
つまり、defaultdict の引数には、規定値が返却値となる関数を指定することができます。もし、複雑な関数が必要な場合は lambda 関数ではなく、通常の def で定義した上で引数に渡すことも可能です。
例えば、以下のように def で定義した関数を渡すことも可能です。
import collections
def init_dict():
# 本来複雑な処理を書けるが例として1を返却するのみ
return 1
data = ["A", "B", "A", "C", "D", "B", "A", "B", "D"]
dict_count = collections.defaultdict(init_dict)
for key in data:
dict_count[key] += 1
print(dict_count)【実行結果】
defaultdict(<function init_dict at 0x000001294089A170>, {'A': 4, 'B': 4, 'C': 2, 'D': 3})この時、関数自体を渡すので () をつけずに「init_dict」を渡すことに注意しましょう。なお、上記は例として非常に簡単な 1 を返す関数にしましたが、より複雑な条件の初期化処理を書いてももちろん構いません。
defaultdict は dict のサブクラス
上記で紹介してきた defaultdict は、dict のサブクラスとなっているため、dictと同じように各種メソッドを使って扱うことができます。
まとめ
Pythonで規定値を持つ辞書を定義する collections モジュールの defaultdict について解説しました。
リストの要素数カウント例で defaultdict の基本を説明しました。defaultdict は、dict のサブクラスであるため dict と同様に各種メソッドが使用できます。
また、defaultdict の引数には、規定値が返却値となる関数を指定することができますので状況によりうまく使いこなしてください。
上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。


.jpg)
.jpg)
.jpg)
.jpg)