Pythonの辞書(dictionary)において、キー(Key)と値(Value)の関係を逆転させたい場合があります。これは、通常の検索(キーから値を引く)ではなく、値からキーを特定したい場合(逆引き)に有用です。
辞書内包表記(Dictionary Comprehension)を使用することで、この処理を簡潔かつ高速に実装する方法を解説します。
解決したい課題
通常、辞書は「キー → 値」の一方向の検索に最適化されています。しかし、データ解析やネットワーク処理などにおいて、「値 → キー」の参照を行いたいシーンがあります。 ここでは、ドメイン名とIPアドレスの対応表を例に、IPアドレスからドメイン名を検索できる逆引き辞書を作成します。
実装例:DNSレコードの逆引き変換
ドメイン名をキー、IPアドレスを値として持つ辞書を反転させます。
ソースコード
# ドメイン名(Key)とIPアドレス(Value)の対応辞書
dns_forward_lookup = {
"example.com": "93.184.216.34",
"google.com": "142.250.196.14",
"python.org": "45.55.99.72"
}
# 辞書内包表記を使ってキーと値を入れ替える
# {新しいキー: 新しい値 for 元のキー, 元の値 in 辞書.items()}
dns_reverse_lookup = {ip: domain for domain, ip in dns_forward_lookup.items()}
# 結果の確認
print("--- 元の辞書(ドメイン -> IP) ---")
print(dns_forward_lookup)
print("\n--- 入れ替え後の辞書(IP -> ドメイン) ---")
print(dns_reverse_lookup)
# 逆引きの実行例
target_ip = "142.250.196.14"
if target_ip in dns_reverse_lookup:
print(f"\nIPアドレス {target_ip} のドメインは {dns_reverse_lookup[target_ip]} です。")
実行結果
--- 元の辞書(ドメイン -> IP) ---
{'example.com': '93.184.216.34', 'google.com': '142.250.196.14', 'python.org': '45.55.99.72'}
--- 入れ替え後の辞書(IP -> ドメイン) ---
{'93.184.216.34': 'example.com', '142.250.196.14': 'google.com', '45.55.99.72': 'python.org'}
IPアドレス 142.250.196.14 のドメインは google.com です。
解説
辞書内包表記の構文
{value: key for key, value in d.items()} という構文により、元の辞書 d の各要素に対してループ処理を行いながら、キーと値を逆転させた新しい辞書を生成します。 items() メソッドは (key, value) のペアを取得するために必須です。
重要な注意点:値の重複について
辞書のキーは一意(ユニーク)である必要があります。 もし元の辞書で「異なるキーが同じ値を持っている(値が重複している)」場合、入れ替えを行うと後から処理された要素で上書きされ、データが消失します。
# 値が重複している例
scores = {"Alice": 80, "Bob": 80}
# 入れ替えると...
reversed_scores = {score: name for name, score in scores.items()}
# 結果: {80: 'Bob'} ('Alice'の情報は消える)
変換元の辞書の値が一意であることが保証されていない場合、この手法はデータの損失を招く可能性があるため、値の重複チェックを行うか、値をリストとして保持する(defaultdict(list)などを使用する)別の設計が必要です。
