辞書と集合の応用

Pythonの辞書(dictionary)と集合(set)は、これまでに学んだ基本操作だけでなく、組み合わせて使うことで非常に強力なデータ処理を実現できます。複雑に見えるアルゴリズムや、大量のデータから特定の条件を抽出する作業も、これらの特性を活かせばわずか数行でシンプルに記述可能です。この記事では、実務でもよく使われる辞書と集合の応用的な使い方について解説します。
辞書の応用例
辞書は「キー」をもとにしたデータの瞬時な検索が強みですが、データの「分類」や「集計(カウント)」のベースとしても非常に重宝されます。
1. 辞書でカウント(出現回数)を管理する
データ分析やテキスト処理の現場で頻出する「どの要素が何回現れたか」を集計するコードです。基本に忠実な記述方法と、実務でよく使われるスマートな書き方の2種類を押さえましょう。
# 文字のカウントを辞書で管理
text = "banana"
count_dict = {}
# 基本的な書き方(if文による分岐)
for char in text:
if char in count_dict:
count_dict[char] += 1
else:
count_dict[char] = 1
print(count_dict) # 出力: {'b': 1, 'a': 3, 'n': 2}
# 【応用】get()メソッドを使うと、上記のif文をわずか1行に短縮できます
count_dict_smart = {}
for char in text:
# キーがなければ0を返し、そこに1を足す
count_dict_smart[char] = count_dict_smart.get(char, 0) + 1
print(count_dict_smart) # 出力: {'b': 1, 'a': 3, 'n': 2}
get(char, 0) を使うことで、「まだ辞書にその文字(キー)が登録されていなければ、初期値として0を用意する」という処理が1行で表現できるため、コードの視認性が大幅に向上します。
2. 辞書を使ったデータのマッピング(条件分岐の代用)
辞書は、データとデータの「対応関係」を固定するのに最適です。また、大量の if-elif 文を書く代わりに、辞書を使って処理をスッキリさせる「テーブル駆動」と呼ばれるテクニックにも応用できます。
# 国名と首都のマッピング
capitals = {
"Japan": "Tokyo",
"France": "Paris",
"USA": "Washington D.C."
}
# 国名に基づいて首都を取得
country = "Japan"
print(capitals[country]) # 出力: Tokyo
集合の応用例
集合の応用は、単一のリストに対するデータクレンジングだけでなく、複数のシステムやファイルから出力された「リスト同士のデータ突合(比較)」で真価を発揮します。
1. リストの重複を排除する
前章でおさらいした通り、リストを一度 set() に通すだけで、一瞬で重複のないクリーンなデータ群が得られます。
# リストから重複を排除
numbers = [1, 2, 2, 3, 4, 4, 5]
unique_numbers = set(numbers)
print(unique_numbers) # 出力: {1, 2, 3, 4, 5}
2. 集合演算を使ったデータの比較(差分の抽出など)
例えば、「昨日のメルマガ会員リスト」と「今日のメルマガ会員リスト」を比較して、新しく登録した人(差分)や、どちらにも共通して残っている人を抽出するようなケースで集合演算は大活躍します。
# 2つの商品カテゴリリストの比較
store_a_products = {"apple", "banana", "cherry"}
store_b_products = {"banana", "cherry", "date"}
# 両方の店舗で扱っている共通商品(積集合)
common_products = store_a_products & store_b_products
print(common_products) # 出力: {'banana', 'cherry'}
# A店だけで扱っている限定商品(差集合)
exclusive_a_products = store_a_products - store_b_products
print(exclusive_a_products) # 出力: {'apple'}
辞書と集合の組み合わせ(キーの集合演算)
辞書と集合を組み合わせる高度なテクニックとして、「辞書のキー一覧(keys())をそのまま集合と見なして比較する」というアプローチがあります。これを使うと、2つの異なるデータ(例:2つのユーザー設定情報)の間で、共通する設定項目や片方にしかない項目を瞬時に洗い出すことができます。
# 2つのユーザープロファイル辞書
user_a = {"name": "Alice", "age": 25, "city": "Tokyo"}
user_b = {"name": "Bob", "age": 30, "email": "bob@example.com"}
# 辞書のキー同士で積集合(共通する項目名)を求める
# Pythonの keys() が返すオブジェクトは、そのまま「&」や「-」の集合演算子が使えます
common_keys = user_a.keys() & user_b.keys()
print(common_keys) # 出力: {'name', 'age'}
# user_aにしか存在しない項目名を求める(差集合)
unique_a_keys = user_a.keys() - user_b.keys()
print(unique_a_keys) # 出力: {'city'}
ワンランク上の応用:辞書・集合内包表記
Pythonには、リストの作成を簡潔に書く「リスト内包表記」がありますが、これは辞書や集合でも同様に使えます。既存のデータから特定の条件を満たす要素だけを抜き出した新しい辞書や集合を、スマートに生成することができます。
# 1. 辞書内包表記:元のデータから20歳以上の人だけを抽出した新しい辞書を作る
members = {"Alice": 25, "Bob": 18, "Charlie": 30}
adult_members = {name: age for name, age in members.items() if age >= 20}
print(adult_members) # 出力: {'Alice': 25, 'Charlie': 30}
# 2. 集合内包表記:リストから特定の文字で始まる要素だけを集めた集合を作る
words = ["apple", "apricot", "banana", "avocado", "cherry"]
# 'a'で始まる単語だけを集合(重複なし)として格納
a_words_set = {w for w in words if w.startswith("a")}
print(a_words_set) # 出力: {'apple', 'avocado', 'apricot'}
まとめ
辞書と集合は、組み合わせて活用したり、get() メソッドによるカウント初期化や内包表記といったPython独自の構文と組み合わせることで、その真価が何倍にも膨らみます。ただデータを格納するだけでなく、「キーを集合として演算させる」「内包表記で1行でフィルタリングする」といった応用テクニックを身につけることで、実務のデータ処理コードが驚くほど洗練されます。これらの強力な道具を自由に組み合わせ、Pythonらしいクリーンで高速なプログラムを目指しましょう。