👻

Pythonの辞書型を使いこなすための基本操作方法と応用テクニック

2023/05/09に公開

はじめに

pythonでよく使う辞書型について、様々な組み込みのメソッドや便利メソッドをまとめました。
どれか一つでも役に立つものがあれば幸いです。

カリキュラムは以下となっています。

  1. 辞書への読み取り処理
  2. 辞書への書き込み処理
  3. 辞書の定義

辞書への読み取り処理

以下辞書はdとします。

キー(key)とバリュー(value)の取得

  • d.keys()
    全てのkeyが取得ができます。型はdict_keysです。

特定の要素が辞書内にあるかどうかを確認する場合は、inを使って次のように記述します。

d = {"a":1}
x = "b" in d # x = False
y = "a" in d # y = True

余談ですが、dict_keysは集合演算ができます。

具体的には、次のように記述します。

d1 = {"a":1,"b":3}
d2 = {"b":2,"c":4}
d1.keys() & d2.keys() # {'b'}

集合演算で出力されるオブジェクトの型はsetになります。(dict_keysのままではない)

  • d.values()
    全てのvalueが取得できます。型はdict_valuesです。

  • d.items()
    全ての(key,value)の組が取得できます。型はdict_itemsです。

keyとvalueの入れ替えは、次のように記述します。

{v:k for k,v in d.items()}

get: キー(key)に対応するバリューの取得

一般的に辞書型では次のように値を取得します。

d = {"a":1}
d["a"]

一方で、指定しようとしたkeyが辞書内にない場合も実際はあります。

上記の手法のように辞書にアクセスするとエラーとなってしまいます。

d = {"a":1}
d["b"] # Error

get()メソッドを使うと、指定したキーが辞書内に存在しない場合でもエラーを回避できます。
getは第一引数はkey、第二引数はkeyが存在しなかった場合に返す値です。
第二引数のdefaultはNoneです。

具体的には、次のように記述します。

d = {"a":1}
d.get("b") # Errorにはならない
d.get("b", "hoge") # hogeが返り値で取得できる。

getを使わずにinKeyErrorを使う手法もありますが、コード量が長くなるのでget推奨です。

辞書への書き込み処理

setdefaultを用いた代入

辞書にaというkeyがなければ0、aというkeyがあれば何もしないという処理を行うことを考えます。

これはinをif文で用いることで実装できますが、setdefaultを使えば一行で書くことができます。
setdefaultの第一引数はkey、第二引数はkeyが存在しなかった場合に代入する値です。

具体的には、次のように記述します。

d = {"a":1}
d = d.setdefault("a",0) # 辞書dにaというkeyがあるのでパス
d = d.setdefault("b",0) # 辞書dにbというkeyがないのでd['b'] = 2
d  # {'a': 1, 'b': 2}

setdefaultを使うよりも後述するdefaultdictを用いる方が良いケースもあります。

辞書の要素の削除

辞書の要素の削除はremoveclearpoppopitemで行うことができます。
poppopitemはそれぞれvalue、keyとvalueの組が返り値で与えられます。
またPython3.7以降は辞書の順序が保持されるようになっており、popitem()はLIFO(後入れ先出し)で要素を削除します。

それぞれ具体的には、次のように記述します。

d = {"a":1, "b":2}
d.remove("b") # d = {"a":1}
d = {"a":1, "b":2}
d.clear() # d = {}
d = {"a":1, "b":2}
x = d.pop("b") # d = {"a":1}, x = 2
d = {"a":1, "b":2}
y = d.popitem() # d = {"a":1}, y = ("b",2)

またpopは指定したkeyがない場合は第二引数で返り値を指定できます。

x = d.pop("XXXX",100) # x = 100

辞書の連結

辞書の連結方法は3つあります。

  1. **を用いた連結
  2. |を用いた連結(Python3.9以降)
  3. d.update

この内d.updateは元の辞書dが変更されます。

具体的には、次のように記述します。

d1 = {"a":1}
d2 = {"b":2}

d3 = {**d1,**d2} # d3 = {'a': 1, 'b': 2}
d4 = d1 | d2 # d4 = {'a': 1, 'b': 2}
d1.update(d2) # d1が更新される

辞書の定義

defaultdictを用いた定義

defaultdictはkeyが存在しない場合に自動的にデフォルト値を返す特殊な辞書です。

具体的には以下のように使います。

from collections import defaultdict

d = defaultdict(int) # `int`は呼び出された時にデフォルト値として0を返す
d["a"] += 1 # Errorが起きずにd["a"] = 0で初期化される
d # d = {'a': 1}

これを用いることでsetdefaultを使う必要がなくなります。
プロジェクトによって適宜使い分けると良いでしょう。

余談ですが、defaultdictでは初期値を自分で指定できます。

d =  defaultdict(lambda: 'default')

__missing__を用いた定義

__missing__は、Pythonの組み込み辞書型であるdictが持つ特殊メソッドの一つです。__missing__メソッドは、辞書からキーを取得できなかった場合に呼び出されます。

具体的には、次のように記述します。

class CustomDict(dict):
    def __missing__(self, key):
        return f"default_value_for_{key}"

d = CustomDict()
d['a'] = 1

print(d['a'])  # 1
print(d['b'])  # default_value_for_b

OrderedDictを用いた定義

OrderedDictは、辞書型であるdictのサブクラスで、値が挿入された順序を保持する辞書です。

(一方でPython3.7以降は辞書の順序が保持されるようになったので、現在はあまり使わないかもしれませんが、、、)

具体的には、次のように記述します。

from collections import OrderedDict

d = OrderedDict()

d['one'] = 1
d['two'] = 2

for key, value in my_dict.items():
    print(key, value) # 順番に表示される 

おわりに

上記を知っていればPythonの辞書型について恐らく困ることはないと思います。

少しでも役に立てば幸いです!!

Discussion