Pythonの標準ライブラリに含まれるcollectionsモジュールには、データ操作を便利にするさまざまなツールが揃っています。その中でも、defaultdictはとても強力な辞書型オブジェクトです。今回は、defaultdictの使い方や活用シーン、便利な関数をまとめてご紹介します。
defaultdictとは?
通常の辞書と同様にキーと値のペアを保持するデータ構造ですが、大きな違いは 「キーが存在しないときのデフォルト値を簡単に設定できる」 ところです。これにより、キーの存在チェックをしなくてもスムーズにデータの追加や更新が行えます。
例えば、キーがなければ自動で「0」を設定するなどの使い方が可能です。早速、基本的な使い方から見ていきましょう。
基本的な使い方
from collections import defaultdict
# デフォルト値として0を持つdefaultdictを作成
d = defaultdict(int)
print(d['a']) # 出力: 0
d['a'] += 1 # 存在しないキーでも0から開始され、1になる
print(d) # 出力: defaultdict(<class 'int'>, {'a': 1})
print(d['a']) # 出力: 1
上記の例では、int
(整数型)をデフォルト値として設定しています。int()
は0を返すので、キーが存在しない場合は自動的に0がセットされ、1が足されます。こういった設定は、カウントの操作や初期値が決まっているデータに非常に便利です。
listやsetとの組み合わせ
1. リストをデフォルト値にする場合
キーごとにリストを持たせることができ、データをリストに追加していく用途に便利です。
# リストをデフォルト値にしたdefaultdict
d_list = defaultdict(list)
d_list['fruits'].append('apple')
d_list['fruits'].append('banana')
print(d_list) # 出力: defaultdict(<class 'list'>, {'fruits': ['apple', 'banana']})
2. setをデフォルト値にする場合
set
をデフォルト値にすることで、一意の要素のみを追加するケースにも適しています。重複データが自然に排除されるため、カテゴリ別のデータ管理に使いやすいです。
# セットをデフォルト値にしたdefaultdict
d_set = defaultdict(set)
d_set['fruits'].add('apple')
d_set['fruits'].add('apple') # 重複は追加されない
print(d_set) # 出力: defaultdict(<class 'set'>, {'fruits': {'apple'}})
lambda関数で初期値をカスタマイズ
labmda関数を使って任意のデフォルト値を設定することも可能です。例えば、キーがない場合に「unknown」という文字列を返したいときは以下のようにします。
# デフォルト値として「unknown」を持つdefaultdict
d = defaultdict(lambda: 'unknown')
print(d['unknown_key']) # 出力: unknown
lambda
で柔軟に初期値を設定できるため、特定のデータが欠けている場合の補完や、デフォルトの説明文を設定したい場合にも使えます。
辞書の入れ子構造
データ構造が多層にわたるとき、defaultdict
をネストして利用すると非常に便利です。多次元のデータを扱う場合も、キーが存在しないことでエラーが発生する心配がなくなります。
# 入れ子構造のdefaultdict
nested_dict = defaultdict(lambda: defaultdict(int))
nested_dict['user1']['score'] += 10
nested_dict['user2']['score'] += 20
print(nested_dict) # 出力: defaultdict(<function <lambda> at ...>, {'user1': defaultdict(<class 'int'>, {'score': 10}), 'user2': defaultdict(<class 'int'>, {'score': 20})})
このように、多層構造を扱う場合でもシンプルに記述できるため、データ構造の可読性が向上します。
collections.Counterの代わりとして利用する
defaultdict(int)
を使うと、キーごとの数をカウントするCounter
としても利用できます。この方法は頻度分析などで活用することができます。
d = defaultdict(int)
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
for word in words:
d[word] += 1
print(d) # 出力: defaultdict(<class 'int'>, {'apple': 3, 'banana': 2, 'orange': 1})
Counter
についてはこちらの記事で解説しております。
データのグループ化に利用
リストをデフォルト値に設定すると、カテゴリごとにデータをまとめる処理が簡単になります。データを分類・グループ化する際に便利です。
data = [('fruit', 'apple'), ('fruit', 'banana'), ('vegetable', 'carrot'), ('fruit', 'orange'), ('vegetable', 'spinach')]
grouped_data = defaultdict(list)
for category, item in data:
grouped_data[category].append(item)
print(grouped_data) # 出力: defaultdict(<class 'list'>, {'fruit': ['apple', 'banana', 'orange'], 'vegetable': ['carrot', 'spinach']})
上記のコードでは、data
の項目をカテゴリごとに分け、defaultdict
で整理しています。これにより、カテゴリごとのデータ集計が非常にシンプルに書けます。
defaultdictで欠損データの補完
デフォルト値を設定することで、キーが存在しない場合にエラーを起こさずに処理を進めることができます。例えば、プロフィール情報の辞書でキーが欠けているときにデフォルトの値で補完できます。
data = defaultdict(lambda: 'unknown', {'name': 'Alice', 'age': 25})
print(data['name']) # 出力: Alice
print(data['gender']) # 出力: unknown
キーが存在しない場合に「unknown」を返すことで、欠損データがあってもエラーが発生しにくくなり、データの補完処理が簡単に行えます。
まとめ
defaultdict
は、デフォルト値を設定できることで辞書の柔軟性を高め、エラーを防ぎながらコードをスッキリと書ける非常に便利なツールです。特に以下のような使い方が便利です。
defaultdict(int)
:カウンターとして使用defaultdict(list)
:データのグループ化defaultdict(set)
:一意の値を管理defaultdict(lambda: デフォルト値)
:カスタムデフォルト値で補完
Pythonのデータ処理を効率化するために、ぜひdefaultdict
を活用してみてください!