Dict
Dictionary (辞書, Dict) は、 Key と Value (値)を対応づけるデータ構造です。連想配列 (associative array) とも言われます。 Java では Map や HashMap などが対応します。
{'key0': 'val0', 'key1': 'val1' }
主な用途は2通りです。
- あるデータの複数の属性を表すときに使う。例えば、ある学生の氏名や住所、メールアドレスなどの複数の属性を列挙したい。
- 複数の要素がある集合に属していて、そのキーと要素を結びつける。例えば、あるクラスの学生ID (key) と各学生の情報(value) を結びつけるとか、商品番号 (key) と商品情報 (value) とかね。
あと、dict に含まれる key を検索するときの平均計算量は O(1) のようです(参考)。
以下、プログラムにおける使い方を簡単にまとめます(プログラム)。
初期化
dct = {'key0': 'val0', 'key1': 'val1' }
print(dct) # {'key0': 'val0', 'key1': 'val1'}
dct2 = dict(key0='val0', key1='val1')
print(dct2) # {'key0': 'val0', 'key1': 'val1'}
要素アクセス
key を使って value を検索するときに使います。
print(dct['key1']) # val1
print(dct.get('key1')) # val1
print('key2' in dct) # key に含まれるか、出力 False
# print(dct['key2']) 例外発生
print(dct.get('key2')) # None
print(dct.get('key2', 'valX')) # valX (default value)
要素追加・削除
dct['key2'] = 'val2' # 挿入
print(dct) # {'key0': 'val0', 'key1': 'val1', 'key2': 'val2'}
dct['key1'] = {} # 挿入(dict を値として上書き)
print(dct) # {'key0': 'val0', 'key1': {}, 'key2': 'val2'}
dct['key1']['keyA'] = 'valA'
print(dct) # {'key0': 'val0', 'key1': {'keyA': 'valA'}, 'key2': 'val2'}
dct['key1']['keyB'] = 'valB'
print(dct) # {'key0': 'val0', 'key1': {'keyA': 'valA', 'keyB': 'valB'}, 'key2': 'val2'}
dct.pop('key2') # 削除
print(dct) # {'key0': 'val0', 'key1': {'keyA': 'valA', 'keyB': 'valB'}}
内包表記を用いた生成
# loop 操作
# 内包表記を用いた dict 生成
# range(4) の要素 i に対し i * i : i なる key, value で初期化
dct = {i * i: i for i in range(4)}
print(dct) # {0: 0, 1: 1, 4: 2, 9: 3}
key, values の取得とループ処理
print(dct.keys()) # dict_keys([0, 1, 4, 9])
print(list(dct.keys())) # [0, 1, 4, 9]
print(dct.values()) # dict_values([0, 1, 2, 3])
print(dct.items()) # dict_items([(0, 0), (1, 1), (4, 2), (9, 3)])
# key に対して loop
for key in dct.keys():
print(f'A:: key:{key}, value: {dct[key]} ')
# value に対して loop
for v in dct.values():
print(f'B:: value: {v}')
# key, value の組に対して loop
for k, v in dct.items():
print(f'C:: key:{k}, value: {v} ')
# 内包表記でも key, value 利用可能
dct3 = {f'key{k}': f'v{v}' for k, v in dct.items()}
print(dct3)
dict の同一性判定
互いに同じ key-value から構成されていれば同一ですが、key-value の表記順は関係ありません。
a = {'name': 'Taro', 'age': 12}
b = {'name': 'Taro', 'age': 22}
print(f'a==b: {a == b} for a: {a} and b: {b}')
# a==b: False for a: {'name': 'Taro', 'age': 12} and b: {'name': 'Taro', 'age': 22}
a['age'] = 22
print(f'a==b: {a == b} for a: {a} and b: {b}')
# a==b: True for a: {'name': 'Taro', 'age': 22} and b: {'name': 'Taro', 'age': 22}
c = {'age': 22, 'name': 'Taro'}
print(f'a==c: {a == c} for a: {a} and c: {c}')
# a==c: True for a: {'name': 'Taro', 'age': 22} and c: {'age': 22, 'name': 'Taro'}
dict のソート
dict 自身はソートされる訳ではないが、
items()
で取得した k,v の組(tuple) の「あつまり」を、
sorted()
でソート済みリストにすることはできる
dict0 = {
'studentA': 78,
'studentC': 80,
'studentB': 82,
'studentD': 84
}
print(sorted(dict0.items())) # [('studentA', 78), ('studentB', 82), ('studentC', 80), ('studentD', 84)]
key-value の組の並びなので、ソート順を変えたい場合、tuple に対して key 関数を作る必要がある。 以下は、value (成績)の降順にソートしたい場合。
def my_key(pair):
k0, v0 = pair
return -v0
で、利用する方は、こんな感じ
print(sorted(dict0.items(), key=my_key)) # [('studentD', 84), ('studentB', 82), ('studentC', 80), ('studentA', 78)]