Pythonの辞書型を使いこなすための基本操作方法と応用テクニック
はじめに
pythonでよく使う辞書型について、様々な組み込みのメソッドや便利メソッドをまとめました。
どれか一つでも役に立つものがあれば幸いです。
カリキュラムは以下となっています。
- 辞書への読み取り処理
- 辞書への書き込み処理
- 辞書の定義
辞書への読み取り処理
以下辞書は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を使わずにinやKeyErrorを使う手法もありますが、コード量が長くなるので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を用いる方が良いケースもあります。
辞書の要素の削除
辞書の要素の削除はremove、clear、pop、popitemで行うことができます。
pop、popitemはそれぞれ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つあります。
-
**を用いた連結 -
|を用いた連結(Python3.9以降) 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