dict(辞書・連想配列)
このページでは豊富な例を用いてPythonのdict(辞書・連想配列)の使い方を学ぶことができます。
特定の操作をより詳しく知りたい場合は、説明欄や各コード例の下に関連するメソッド・関数のリンクをおきますので、
そのリンクからより詳細な説明ページへ飛んでください。
辞書(dict、dictionary)はキー・バリュー形式で複数の値を保持することができるデータ型です。
このような形式のデータ型は他のプログラミング言語で連想配列と呼ばれることがあります。
バージョン3.7以降では辞書の要素の順番が保証されるようになり、
より早く挿入された要素により早い順序が割り当てられるようになりました。
TL;DR
初期化
# {}(波括弧)を使用した初期化
dict1 = {'key1': 'value1', 'key2': 'value2'}
print(dict1)
==> {'key1': 'value1', 'key2': 'value2'}
dict2 = {0: {'inner1': 100, 'inner2': 200}, 'outer1': 300}
print(dict2)
==> {0: {'inner1': 100, 'inner2': 200}, 'outer1': 300}
# キーはハッシュ可能(hashable)な値のみ指定可能(リストオブジェクトはハッシュ不可能)
dict3 = {[1, 2]: 'ABC'}
print(dict3)
==> TypeError: unhashable type: 'list'
# 以下は辞書(dict)クラスのコンストラクタを使用した初期化
# 空オブジェクトの作成
dict3 = dict()
print(dict3)
==> {}
# キーワード引数の使用
dict4 = dict(key1=100, key2=200)
print(dict4)
==> {'key1': 100, 'key2': 200}
# 辞書の使用
dict5 = dict({1: 'value1'})
print(dict5)
==> {1: 'value1'}
# 辞書とキーワード引数の使用
dict6 = dict({True: True}, false=False)
print(dict6)
==> {True: True, 'false': False}
# 反復可能オブジェクトの使用.1
dict7 = dict([('key1', 'value1'), ('key2', 'value2')])
print(dict7)
==> {'key1': 'value1', 'key2': 'value2'}
# 反復可能オブジェクトの使用.2
dict8 = dict(zip(['key1', 'key2'], ['value1', 'value2']))
print(dict8)
==> {'key1': 'value1', 'key2': 'value2'}
関連情報:関数のキーワード引数使用方法
要素の取得
# [](角括弧)を使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
print(dict1['key1'])
==> value1
# getを使用
dict2 = {0: 'zero', 1: 'one'}
print(dict2.get(0))
==> zero
# forでのアクセス.1
# そのままだとkey部分が繰り返される
dict3 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
for key in dict3:
print(key, dict3[key])
==> key1 value1
==> key2 value2
==> key3 value3
# forでのアクセス.2(valuesメソッド)
dict3 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
for value in dict3.values():
print(value)
==> value1
==> value2
==> value3
# forでのアクセス.3
dict3 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
for key, value in dict3.items():
print(key, value)
==> key1 value1
==> key2 value2
==> key3 value3
関連情報:for文の使用方法
要素の代入・追加
# 代入
dict1 = {'py': 'javascript'}
print(dict1)
==> {'py': 'javascript'}
dict1['py'] = 'python'
print(dict1)
==> {'py': 'python'}
# 追加
dict2 = dict()
print(dict2)
==> {}
dict2['key1'] = 'value1'
print(dict2)
==> {'key1': 'value1'}
# 複数の値の更新
dict3 = {'key1': 'value1', 'key2': 'value2'}
print(dict3)
==> {'key1': 'value1', 'key2': 'value2'}
dict3.update(key1='py', key2='js')
print(dict3)
==> {'key1': 'py', 'key2': 'js'}
辞書同士の結合
# updateの使用
dict1 = {0: 'zero'}
dict2 = {1: 'one'}
dict1.update(dict2)
print(dict1)
==> {0: 'zero', 1: 'one'}
# dict2には影響なし
print(dict2)
==> {1: 'one'}
# **の使用
dict1 = {0: 'zero'}
dict2 = {1: 'one'}
joined_dict1 = {**dict1, **dict2}
print(joined_dict1)
==> {0: 'zero', 1: 'one'}
# dict1,dict2には影響なし
print(dict1)
==> {0: 'zero'}
print(dict2)
==> {1: 'one'}
# |演算子(merge operator)の使用
dict3 = {'A': 'apple', 'B': 'banana'}
dict4 = {'B': 'kiwi', 'C': 'orange'}
joined_dict2 = dict3 | dict4
print(joined_dict2)
==> {'A': 'apple', 'B': 'kiwi', 'C': 'orange'}
# dict3,dict4には影響なし
print(dict3)
==> {'A': 'apple', 'B': 'banana'}
print(dict4)
==> {'B': 'kiwi', 'C': 'orange'}
# |=演算子(update operator)の使用
dict3 = {'A': 'apple', 'B': 'banana'}
dict4 = {'B': 'kiwi', 'C': 'orange'}
dict3 |= dict4
print(dict3)
==> {'A': 'apple', 'B': 'kiwi', 'C': 'orange'}
# dict4には影響なし
print(dict4)
==> {'B': 'kiwi', 'C': 'orange'}
要素数の取得
dict1 = dict()
print(len(dict1))
==> 0
dict2 = {1: 100, 2: 200, 3: 300}
print(len(dict2))
==> 3
要素の削除
# del文の使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
del dict1['key1']
print(dict1)
==> {'key2': 'value2'}
# popの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
return_value1 = dict1.pop('key1')
print(dict1)
==> {'key2': 'value2'}
print(return_value1)
==> value1
# popitemの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
return_value2 = dict1.popitem()
print(dict1)
==> {'key1': 'value1'}
print(return_value2)
==> ('key2', 'value2')
# clearの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
dict1.clear()
print(dict1)
==> {}
要素のコピー
# copyメソッドは浅いコピー
dict1 = {'key1': 'value1', 'key2': {'inner_key1': 'inner_value1'}}
copied_dict1 = dict1.copy()
print(copied_dict1)
==> {'key1': 'value1', 'key2': {'inner_key1': 'inner_value1'}}
# 浅いコピーなので双方に影響が出る要素がある
dict1['key1'] = '###'
dict1['key2']['inner_key1'] = '@@@'
print(dict1)
==> {'key1': '###', 'key2': {'inner_key1': '@@@'}}
print(copied_dict1)
==> {'key1': 'value1', 'key2': {'inner_key1': '@@@'}}
from copy import deepcopy
# 深いコピー(copyモジュールのdeepcopy関数を使用)
dict2 = {'key1': 'value1', 'key2': {'inner_key1': 'inner_value1'}}
copied_dict2 = deepcopy(dict2)
print(copied_dict2)
==> {'key1': 'value1', 'key2': {'inner_key1': 'inner_value1'}}
# 深いコピーなので双方に影響が出ない
dict2['key1'] = '###'
dict2['key2']['inner_key1'] = '@@@'
print(dict2)
==> {'key1': '###', 'key2': {'inner_key1': '@@@'}}
print(copied_dict2)
==> {'key1': 'value1', 'key2': {'inner_key1': 'inner_value1'}}
要素のソート
# キーで並び替え
dict1 = {'b': 3, 'c': 2, 'a': 1}
sorted_list1 = sorted(dict1.items(), key=lambda e: e[0])
print(sorted_list1)
==> [('a', 1), ('b', 3), ('c', 2)]
print(dict(sorted_list1))
==> {'a': 1, 'b': 3, 'c': 2}
# 値で並び替え
dict1 = {'b': 3, 'c': 2, 'a': 1}
sorted_list2 = sorted(dict1.items(), key=lambda e: e[1])
print(sorted_list2)
==> [('a', 1), ('c', 2), ('b', 3)]
print(dict(sorted_list2))
==> {'a': 1, 'c': 2, 'b': 3}
関連情報:sorted関数の使用方法
関連情報:lambda式(ラムダ)の使用方法
要素の検索
# キーの検索
# inの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
print('key1' in dict1)
==> True
print('python' in dict1)
==> False
# getの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
print(dict1.get('key2'))
==> value2
print(dict1.get('python'))
==> None
# バリューの検索
# inの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
print('value1' in dict1.values())
==> True
print('python' in dict1.values())
==> False
# キー・バリューのペア検索
# inの使用
dict1 = {'key1': 'value1', 'key2': 'value2'}
print(('key1', 'value1') in dict1.items())
==> True
print(('key1', 'python') in dict1.items())
==> False
辞書同士の比較
dict1 = {'key1': 'value1', 'key2': {'inner': 0}}
dict2 = {'key2': {'inner': 0}, 'key1': 'value1'}
dict3 = {'key1': 'value1', 'key2': {'inner': 1000}}
print(dict1 == dict2)
==> True
print(dict1 == dict3)
==> False
辞書内包表記
tuple1 = (0, 1, 2)
dict1 = {x: x + 1 for x in tuple1}
print(dict1)
==> {0: 1, 1: 2, 2: 3}
list1 = ['zero', 'one', 'two']
dict2 = {key: value for key, value in enumerate(list1)}
print(dict2)
==> {0: 'zero', 1: 'one', 2: 'two'}
関連情報:リスト内包表記の使用方法
解説
初期化
辞書(dict・dictionary)は主に2種類の方法で初期化することができます。
1つ目は{}
(波括弧)を使用する方法です。
波括弧内に:
(コロン)区切りでキー:バリュー
と宣言することで1つの要素を表すことができます。
複数の要素を定義したい場合は要素と要素の間を,
(セミコロン)で区切ってください。
2つ目は辞書クラス(dict class)のコンストラクタを用いる方法です。
辞書クラスのコンストラクタは引数として様々な形式の引数、オブジェクトを取ることができます。
引数を指定しない場合は空の辞書オブジェクトを生成します。
より詳しく知りたい場合は
class dict - Pythonドキュメント
を参照してください。
キーを指定する際の注意点として、キーに指定する値は
ハッシュ可能(hashable)
でなければならない点が挙げられます。
これはつまり、辞書や
リスト(list)
などのミュータブルな値はキーとして使用できないことを意味しています。
# {}(波括弧)を使用した初期化
dict1 = {'py': 'Python', 'js': 'JavaScript'}
print(dict1)
==> {'py': 'Python', 'js': 'JavaScript'}
# 以下は辞書(dict)クラスのコンストラクタを使用した初期化
# 空オブジェクトの作成
dict2 = dict()
print(dict2)
==> {}
# キーワード引数の使用
dict3 = dict(one=1, two=2, three=3)
print(dict3)
==> {'one': 1, 'two': 2, 'three': 3}
# 辞書の使用
dict4 = dict({0: 'zero', 1: 'one'})
print(dict4)
==> {0: 'zero', 1: 'one'}
# 辞書とキーワード引数の使用
dict5 = dict({'foo': 'FOO'}, bar='BAR')
print(dict5)
==> {'foo': 'FOO', 'bar': 'BAR'}
# 反復可能オブジェクトの使用
dict6 = dict([('key1', 'value1'), ('key2', 'value2')])
print(dict6)
==> {'key1': 'value1', 'key2': 'value2'}
関連情報:関数のキーワード引数使用方法
要素の取得
辞書オブジェクトの要素の取得方法は複数あります。 ここでは代表的な例をいくつか挙げます。
1つ目は[]
(角括弧)を使用する方法です。
角括弧内にキーの値を指定することで、そのキーに紐付いたバリューを取得することができます。
指定したキーが辞書オブジェクトに存在しない場合はKeyError
が発生します。
2つ目はget
メソッドを使用する方法です。
引数にキーを指定して紐付いたバリューを戻り値として取得することができます。
指定したキーが辞書オブジェクトに存在しない場合はNone
が戻り値となります。
3つ目は
辞書ビューオブジェクト(Dictionary view objects)
や
for文
使用して取得する方法です。
keys
メソッドやvalues
メソッドやitems
メソッドを使用することで辞書オブジェクトの各要素にアクセスすることができます。
目的に沿った方法を選択してください。
辞書オブジェクトをそのままfor文に与えると、キーの値を取得して繰り返し処理を行うことができます。
# [](角括弧)を使用
dict1 = {'py': 'Python', 'js': 'JavaScript'}
print(dict1['py'])
==> Python
# getを使用
dict1 = {'py': 'Python', 'js': 'JavaScript'}
print(dict1.get('py'))
==> Python
# forでのアクセス.1
# そのままだとkey部分が繰り返される
dict1 = {'py': 'Python', 'js': 'JavaScript'}
for key in dict1:
print(key, dict1[key])
==> py Python
==> js JavaScript
# forでのアクセス.2(valuesメソッド)
dict1 = {'py': 'Python', 'js': 'JavaScript'}
for value in dict1.values():
print(value)
==> Python
==> JavaScript
# forでのアクセス.3
dict1 = {'py': 'Python', 'js': 'JavaScript'}
for key, value in dict1.items():
print(key, value)
==> py Python
==> js JavaScript
要素の代入・追加
特定のキーに紐づくバリューに対して代入を行いたい場合、
角括弧にキーを指定し、=
演算子を使用して新しいバリューを代入することができます。
新たなキー・バリューのペアを追加したい場合は、新しいキーの値を角括弧内に指定し、=
演算子を使用してバリューを代入します。
複数のバリューを一度に代入・更新したい場合はupdate
メソッドの使用を検討してください。
引数として辞書オブジェクトやキーワード引数の形式で値を指定することができます。
# 代入
dict1 = {'key1': 'value1'}
print(dict1)
==> {'key1': 'value1'}
dict1['key1'] = True
print(dict1)
==> {'key1': True}
# 追加
dict2 = dict()
print(dict2)
==> {}
dict2[0] = 100
print(dict2)
==> {0: 100}
# 複数の値の更新
dict3 = {0: {}, 1: {'key1': 'val1'}}
print(dict3)
==> {0: {}, 1: {'key1': 'val1'}}
dict3.update({0: {'key0': 'added_value'}, 1: None})
print(dict3)
==> {0: {'key0': 'added_value'}, 1: None}
辞書同士の結合
辞書同士を結合させる方法として、updateメソッド、**(アスタリスク2つ)、|演算子、|=演算子を紹介します。
update
メソッドは「引数で与えた辞書オブジェクト」の要素を「呼び出した辞書オブジェクト」に結合させて変化させます。
**
(アスタリスク2つ)を使用して辞書オブジェクトを展開させつつ初期化すると、
2つの辞書オブジェクトの値が結合した辞書オブジェクトを得ることができます。
|
演算子(merge operator)を使用すると、2つの辞書オブジェクトの値を結合させた辞書オブジェクトを得ることができます。
|=
演算子(update operator)を使用すると、「左辺の辞書オブジェクト」に「右辺の辞書オブジェクト」の要素を結合させることができます。
上記いずれの方法も、同一のキーが存在する場合には、後から与えた辞書オブジェクトのバリューで上書きされます。
# updateの使用
dict1 = {1: 100, 2: 150}
dict2 = {2: 200}
dict1.update(dict2)
print(dict1)
==> {1: 100, 2: 200}
# dict2には影響なし
print(dict2)
==> {2: 200}
# **の使用
dict1 = {1: 100, 2: 150}
dict2 = {2: 200}
joined_dict1 = {**dict1, **dict2}
print(joined_dict1)
==> {1: 100, 2: 200}
# dict1,dict2には影響なし
print(dict1)
==> {1: 100, 2: 150}
print(dict2)
==> {2: 200}
# |演算子(merge operator)の使用
dict3 = {'key1': 'value1', 'key2': 'value2'}
dict4 = {'key2': 'Python', 'key3': 'value3'}
joined_dict2 = dict3 | dict4
print(joined_dict2)
==> {'key1': 'value1', 'key2': 'Python', 'key3': 'value3'}
# dict3,dict4には影響なし
print(dict3)
==> {'key1': 'value1', 'key2': 'value2'}
print(dict4)
==> {'key2': 'Python', 'key3': 'value3'}
# |=演算子(update operator)の使用
dict3 = {'key1': 'value1', 'key2': 'value2'}
dict4 = {'key2': 'Python', 'key3': 'value3'}
dict3 |= dict4
print(dict3)
==> {'key1': 'value1', 'key2': 'Python', 'key3': 'value3'}
# dict4には影響なし
print(dict4)
==> {'key2': 'Python', 'key3': 'value3'}
要素数の取得
組み込み関数のlen
を使用すると、引数で与えた辞書オブジェクトの要素数を取得することができます。
dict1 = {}
print(len(dict1))
==> 0
dict2 = {1: 10, 2: 20}
print(len(dict2))
==> 2
要素の削除
要素を削除する方法として、del文、popメソッド、popitemメソッド、clearメソッドを紹介します。
del
文は[]
(角括弧)で指定したキー・バリューの要素を辞書オブジェクトから削除します。
pop
メソッドは引数でキーを指定し、
そのキー・バリューの要素を削除して、削除したバリューのみを戻り値として返します。
popitem
メソッドは呼び出した辞書オブジェクトの末尾の要素を削除し、削除したキー・バリューのペアをタプル(tuple)型のオブジェクトにして戻り値として返します。
clear
メソッドは呼び出した辞書オブジェクトの要素すべてを削除します。
# del文の使用
dict1 = {'py': 'python', 'js': 'javascript'}
del dict1['js']
print(dict1)
==> {'py': 'python'}
# popの使用
dict1 = {'py': 'python', 'js': 'javascript'}
return_value1 = dict1.pop('js')
print(dict1)
==> {'py': 'python'}
print(return_value1)
==> javascript
# popitemの使用
dict1 = {'py': 'python', 'js': 'javascript'}
return_value2 = dict1.popitem()
print(dict1)
==> {'py': 'python'}
print(return_value2)
==> ('js', 'javascript')
# clearの使用
dict1 = {'py': 'python', 'js': 'javascript'}
dict1.clear()
print(dict1)
==> {}
要素のコピー
辞書オブジェクトのコピーをする方法として、copyメソッドとcopyモジュールのdeepcopy関数を紹介します。
copy
メソッドは辞書オブジェクトの浅いコピー(shallow copy)を生成します。
浅いコピーの挙動はコード例を参照してください。
Pythonの標準ライブラリであるcopyモジュールのdeepcopy
関数は深いコピー(deep copy)を生成します。
浅いコピーと深いコピーの挙動に気をつけて使い分けてください。
# copyメソッドは浅いコピー
dict1 = {'py': 'python', 'js': {'full_name': 'javascript'}}
copied_dict1 = dict1.copy()
print(copied_dict1)
==> {'py': 'python', 'js': {'full_name': 'javascript'}}
# 浅いコピーの挙動
copied_dict1['py'] = '###'
copied_dict1['js']['full_name'] = '@@@'
print(dict1)
==> {'py': 'python', 'js': {'full_name': '@@@'}}
print(copied_dict1)
==> {'py': '###', 'js': {'full_name': '@@@'}}
from copy import deepcopy
# 深いコピー(copyモジュールのdeepcopy関数を使用)
dict2 = {'py': 'python', 'js': {'full_name': 'javascript'}}
copied_dict2 = deepcopy(dict2)
print(copied_dict2)
==> {'py': 'python', 'js': {'full_name': 'javascript'}}
# 深いコピーの挙動
copied_dict2['py'] = '###'
copied_dict2['js']['full_name'] = '@@@'
print(dict2)
==> {'py': 'python', 'js': {'full_name': 'javascript'}}
print(copied_dict2)
==> {'py': '###', 'js': {'full_name': '@@@'}}
要素のソート
組み込み関数の sorted を使用して辞書オブジェクトの要素をソートすることができます。
注意
辞書オブジェクトの要素の順序が保証されるのはバージョン3.7以降です。
# キーで並び替え
dict1 = {0: 'b', 2: 'c', 1: 'a'}
sorted_list1 = sorted(dict1.items(), key=lambda e: e[0])
print(sorted_list1)
==> [(0, 'b'), (1, 'a'), (2, 'c')]
print(dict(sorted_list1))
==> {0: 'b', 1: 'a', 2: 'c'}
# 値で並び替え
dict1 = {0: 'b', 2: 'c', 1: 'a'}
sorted_list2 = sorted(dict1.items(), key=lambda e: e[1])
print(sorted_list2)
==> [(1, 'a'), (0, 'b'), (2, 'c')]
print(dict(sorted_list2))
==> {1: 'a', 0: 'b', 2: 'c'}
関連情報:lambda式(ラムダ)の使用方法
要素の検索
要素の検索(存在確認)をするにはinやgetなどを使用することができます。
in
は左辺に指定した要素の値が含まれているとTrue
を返します。
辞書オブジェクトはinの右辺に指定すると、キーに対して探索をします。
そのため、バリューやキー・バリューのペアに対して存在確認をしたい場合はvaluesメソッドや、itemsメソッドを使用してください。
get
メソッドは指定したキーが存在しない場合にNone
が戻り値となることを利用して要素の存在確認を行うことができます。
しかし、キーに紐づくバリュー自体がNone
の要素が存在する場合、判定できなくなってしますので気をつけてください。
# キーの検索
# inの使用
dict1 = {0: 'zero'}
print(0 in dict1)
==> True
print('python' in dict1)
==> False
# getの使用
dict1 = {0: 'zero'}
print(dict1.get(0))
==> zero
print(dict1.get('python'))
==> None
# バリューの検索
# inの使用
dict1 = {0: 'zero'}
print('zero' in dict1.values())
==> True
print('python' in dict1.values())
==> False
# キー・バリューのペア検索
# inの使用
dict1 = {0: 'zero'}
print((0, 'zero') in dict1.items())
==> True
print(('zero', 0) in dict1.items())
==> False
辞書同士の比較
==
演算子で比較した際に、辞書オブジェクトはキー・バリューのペアがすべて同じであればTrue
と判定されます。
この比較が行われる場合、要素の順番は無視されることに気をつけてください。
dict1 = {'py': 'python', 'js': {'fullname': 'javascript'}}
dict2 = {'js': {'fullname': 'javascript'}, 'py': 'python'}
dict3 = {'py': 'python', 'golang': {'name': 'go'}}
print(dict1 == dict2)
==> True
print(dict1 == dict3)
==> False
辞書内包表記
リストの初期化方法の1つとして リスト内包表記 がありますが、辞書の初期化にも辞書内包表記(dictionary comprehension, dict comprehension)があります。
多くの要素を効率よく生成でき、記述も簡潔にすることが可能なので場面にあわせ使用を検討してみてください。
dict1 = {x: x * 100 for x in (0, 1, 2)}
print(dict1)
==> {0: 0, 1: 100, 2: 200}
list1 = ['python', 'javascript', 'java']
dict2 = {str(key): value for key, value in enumerate(list1)}
print(dict2)
==> {'0': 'python', '1': 'javascript', '2': 'java'}
1次情報
辞書型 (dictionary) - Pythonドキュメント
Dictionary Merge & Update Operators - What's New In Python 3.9