Pythonで辞書を作成するdict()と波括弧、辞書内包表記
Pythonで辞書(dict
型オブジェクト)を作成するには様々な方法がある。キーkey
と値value
を一つずつ設定するだけでなく、リストから辞書を作成することも可能。
辞書の要素の追加・削除・存在確認・取得などについては以下の記事を参照。
- 関連記事: Pythonで辞書に要素を追加・更新
- 関連記事: Pythonで辞書の要素を削除するclear, pop, popitem, del
- 関連記事: Pythonで辞書のキー・値の存在を確認、取得(検索)
波括弧{}で辞書を作成
キーと値を個別に指定
波括弧{}
の中にキーkey
と値value
の組み合わせをkey: value
のように書くと辞書が生成される。
{key: value, key: value, ...}
d = {'k1': 1, 'k2': 2, 'k3': 3}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}
辞書には同じキーを2つ以上登録できないため、同じキーを指定した場合は上書きされる。
d = {'k1': 1, 'k2': 2, 'k3': 3, 'k3': 300}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 300}
複数の辞書を結合(マージ)
Python3.5から{**d1, **d2}
という書き方ができるようになった。
以下のように、2つの辞書を結合して新たな辞書を生成できる。元の辞書はそのまま。
d1 = {'k1': 1, 'k2': 2}
d2 = {'k3': 3, 'k4': 4}
d = {**d1, **d2}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}
print(d1)
# {'k1': 1, 'k2': 2}
print(d2)
# {'k3': 3, 'k4': 4}
キーと値を個別に指定するkey: value
の書き方と組み合わせることも可能。
print({**d1, **d2, 'k5': 5})
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5}
3つ以上の辞書でもよい。
d3 = {'k5': 5, 'k6': 6}
print({**d1, **d2, **d3})
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5, 'k6': 6}
同じキーを指定した場合は上書きされる。
d4 = {'k1': 100, 'k3': 300}
print({**d1, **d2, **d3, **d4, 'k5': 500})
# {'k1': 100, 'k2': 2, 'k3': 300, 'k4': 4, 'k5': 500, 'k6': 6}
Python3.5より前のバージョンでは上の書き方はできない。複数の辞書から新たな辞書を生成したい場合は後述のdict(**d1, **d2)
を使う。
また、Python3.9からは|
演算子で複数の辞書のマージができるようになった。詳細は以下の記事を参照。
- 関連記事: Pythonで辞書同士を結合(連結・マージ)
dict型のコンストラクタdict()で辞書を作成
dict
型のコンストラクタdict()
で辞書を作成できる。
引数の指定方法はいくつかある。
キーワード引数で作成
キーワード引数key=value
を指定すると、キーkey
と値value
がそれぞれ登録される。
d = dict(k1=1, k2=2, k3=3)
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}
この場合、キーとして指定できるのは引数名(識別子)として有効な文字列のみ。数字から始まったり、_
以外の記号を含むものは使えない。
同じキーを指定するとエラーになる。
# d = dict(k1=1, k2=2, k3=3, k3=300)
# SyntaxError: keyword argument repeated: k3
キーと値のペアのリストから作成
キーkey
と値value
のペア(タプル(key, value)
など)のリストでも指定できる。
d = dict([('k1', 1), ('k2', 2), ('k3', 3)])
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}
上の例はタプルのリストだが、イテラブルであればリストのタプルやリストのリストなどでもよい。
d = dict((['k1', 1], ['k2', 2], ['k3', 3]))
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}
この場合はキーが重複していてもよい。後ろの要素の値で上書きされる。
d = dict([('k1', 1), ('k2', 2), ('k3', 3), ('k3', 300)])
print(d)
# {'k1': 1, 'k2': 2, 'k3': 300}
キーと値それぞれのリストから作成
zip()
関数を使うとキーのリストと値のリストから辞書を作成できる。リストに限らず、タプルなどでもOK。
keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]
d = dict(zip(keys, values))
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}
例は省略するが、この場合もキーが重複していても問題ない。後ろの要素の値で上書きされる。
リストの値を処理したり条件によって要素を取捨選択したりしたい場合は後述の辞書内包表記を使う。
別の辞書から作成
コンストラクタdict()
の引数に別の辞書オブジェクトを指定すると、その辞書と同じキーと値の辞書が作成される。
d_other = {'k10': 10, 'k100': 100}
d = dict(d_other)
print(d)
# {'k10': 10, 'k100': 100}
このとき生成されるのは浅いコピー(shallow copy)。値として辞書やリストなどのミュータブル(更新可能)オブジェクトを含む場合、それらのオブジェクトはオリジナルとコピー先で同一オブジェクトとなるため、一方が更新されると他方も更新される。深いコピーを生成するにはcopyモジュールのdeepcopy()
を使う。
dict()
の引数に複数の辞書をそのまま指定するとエラー。
d1 = {'k1': 1, 'k2': 2}
d2 = {'k3': 3, 'k4': 4}
# d = dict(d1, d2)
# TypeError: dict expected at most 1 arguments, got 2
上述のように、dict()
ではキーワード引数(key=value
)として要素を指定できるので、辞書に**
をつけてそれぞれの要素をキーワード引数として展開して渡せばよい。
d = dict(**d1, **d2)
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4}
この場合、キーが重複しているとエラーになるので注意。上述のように、Python3.5からは{**d1, **d2}
といった書き方も可能。こちらの場合はキーが重複していても問題ない。
d1 = {'k1': 1, 'k2': 2}
d2 = {'k1': 100, 'k3': 3}
# d = dict(**d1, **d2)
# TypeError: dict() got multiple values for keyword argument 'k1'
d = {**d1, **d2}
print(d)
# {'k1': 100, 'k2': 2, 'k3': 3}
辞書内包表記で辞書を作成
リスト内包表記でリストを作成するように、辞書内包表記で辞書を作成できる。
- 関連記事: Pythonリスト内包表記の使い方
リスト内包表記との違いは、[]
でなく{}
で囲むことと、キーと値の2つを指定すること。
{キー: 値 for 任意の変数名 in イテラブルオブジェクト}
キーと値には任意の式を指定可能。
l = ['Alice', 'Bob', 'Charlie']
d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}
キーと値それぞれのリストから作成する場合はdict()
と同様にzip()
関数を使う。
keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]
d = {k: v for k, v in zip(keys, values)}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}
辞書内包表記ではif
による条件分岐も可能。リストをそのまま辞書にするなら上述のようにdict()
でいいが、値を処理したり条件によって要素を取捨選択したい場合は辞書内包表記が便利。
d = {k: v for k, v in zip(keys, values) if v % 2 == 1}
print(d)
# {'k1': 1, 'k3': 3}
既存の辞書から条件を満たす要素を抽出したり削除したりして新たに辞書を生成するのにも使える。
d = {'apple': 1, 'banana': 10, 'orange': 100}
dc = {k: v for k, v in d.items() if v % 2 == 0}
print(dc)
# {'banana': 10, 'orange': 100}
dc = {k: v for k, v in d.items() if v % 2 == 1}
print(dc)
# {'apple': 1}
dc = {k: v for k, v in d.items() if k.endswith('e')}
print(dc)
# {'apple': 1, 'orange': 100}
dc = {k: v for k, v in d.items() if not k.endswith('e')}
print(dc)
# {'banana': 10}
dc = {k: v for k, v in d.items() if v % 2 == 0 and k.endswith('e')}
print(dc)
# {'orange': 100}
辞書のitems()
メソッドでキーkey
と値value
を取り出している。