辞書型(dict)とは
辞書型(dict)もsetと同じく波括弧 { } を使用しますが、項目(item)として キー(key):値(value) の様にkeyとvalueを対にしてコロン(:)を挟んだ形で格納します。 (dict では一対の key : value を項目(item) と呼びます)具体的には
d = {'温度':15.3, '風速':2.8, '月間降水量':224.5}
d, type(d)
({‘温度’: 15.3, ‘風速’: 2.8, ‘月間降水量’: 224.5}, dict)
となります。dictの中で key はユニーク(一意、重複せず)でなければなりません。またlist、set、そしてdict自身の様なmutableな型をkeyに使用することはできません。tuple を key として使用することは可能ですが、要素にmutableな型を含まないことが前提となります。
中に何も入れない { } は空のdictとなります。dict型は key に value をマッピング(割り付ける)ので、マッピング型のオブジェクトに分類されます。
dict は set と同じく { } の中の順番が異なっても等号が成り立ちます。
{'温度':15.3, '風速':2.8, '月間降水量':224.5} == {'月間降水量':224.5, '温度':15.3, '風速':2.8}
True
valueはkeyを[]に入れて指定すると抽出することができます。つまりkeyがシーケンス型でのインデックスと同じ役割をはたします。
d['温度']
15.3
keyを指定して追加や修正ができます。元のdictに存在しないkeyを指定して代入するとそのkeyが追加され、存在するkeyを指定して代入すると更新されます。
d = {'温度':14.6, '風速':2.9}
print(d)
d['月間降水量'] = 91.0 #存在しないkeyを指定すると追加される
print(d)
d['月間降水量'] = 198.0 #keyが存在する場合は更新される
print(d)
{‘温度’: 14.6, ‘風速’: 2.9}
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 91.0}
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
また、dict は set とは異なり項目の順序が保証されています。(python version 3.7以降)
s = {'温度', '風速', '月間降水量'}
print('set\n',s)
for i in s:
print(i)
d = {'温度': 21.0, '風速': 2.9, '月間降水量': 198.0}
print('\ndict\n',d)
for i in d:
print(i)
set
{‘温度’, ‘月間降水量’, ‘風速’}
温度
月間降水量
風速
dict
{‘温度’: 21.0, ‘風速’: 2.9, ‘月間降水量’: 198.0}
温度
風速
月間降水量
上記の通り set の場合は 代入した順番が勝手に変わっていますが、dict は順番が保存されています。
以下のような内包表記で dict を作成することができます。
{x: x**2 for x in (2, 3, 5)}
{2: 4, 3: 9, 5: 25}
dict型の演算
演算一覧
関数・メソッド・演算子 | 結果 |
---|---|
dict() | dictを作成する関数 |
list(d) | 辞書 d で使われている全てのキーのリストを返す |
len(d) | 辞書 d の項目数を返す |
d[key] | 辞書 d のkeyのvalueを返す keyが無ければ KeyError |
get(key[, default]) | key が辞書にあれば key に対する値を、 そうでなければ default を返す default が与えられなかった場合はNoneを返す |
d[key] = value | d[key] に value を設定する |
setdefault(key[, default]) | key が辞書にあれば、その値を、そうでなければ、 値を default として key を挿入し、 default を返す。 default のデフォルトは None |
del d[key] | d から d[key] を削除する keyが無ければ KeyError |
items() | 辞書の項目 ((key, value)対) の新しいビューを返す |
keys() | 辞書のキーの新しいビューを返す |
values() | 辞書の値の新しいビューを返す。 |
key in d | d がキー key を持っていれば True を、 そうでなければ、 False を返す |
key not in d | d がキー key を持っていれば False を、 そうでなければ、 True を返す |
iter(d) | 辞書のキーのイテレータを返す (iter(d.keys()) へのショートカット) |
reversed(d) | 辞書のキーに対する逆引きイテレータを返す。 (reversed(d.keys())のショートカット) |
clear() | 辞書の全ての項目を消去する |
copy() | 辞書の浅いコピーを返す |
fromkeys(iterable[, value]) | iterable からキーを取り、値を value に設定した、 新しい辞書を作成する |
pop(key[, default]) | key が辞書に存在すればその値を辞書から消去して返し、 そうでなければ default を返す。 default が与えらず、かつ key が辞書に存在しなければ KeyError |
popitem() | 任意の (key, value) 対を辞書から消去して返す。 対は LIFO の順序で返却される。 |
d | other | d と other のキーと値をマージした新しい辞書を作成する。 d と other がキーを共有している場合、otherの値が優先される。 |
d |= other | d を other のキーと値で更新する。 d と other がキーを共有している場合、other の値が優先される |
update([other]) | 辞書の内容を other のキーと値で更新する。 既存のキーは上書きされる。 戻り値は None |
dictの演算の実行例
dict()
まず、dictを作成する方法は以下の通りいろいろあります。ポイントは key : value のペアとして代入していることです。
# dict関数とdictを作成する方法のいろいろ
d1 = {'temp':15.3, 'wind':2.8, 'precip':224.5}
d2 = {'wind':2.8, 'precip':224.5, 'temp':15.3} #順番を変更しても同じと認識される
d3 = dict(temp = 15.3, wind = 2.8, precip = 224.5) #キーワード引数でペア指定
d4 = dict([('temp', 15.3), ('wind', 2.8), ('precip', 224.5)])
d5 = dict((['temp', 15.3], ['wind', 2.8], ['precip', 224.5]))
d6 = dict((('temp', 15.3), ('wind', 2.8), ('precip', 224.5)))
d7 = dict([['temp', 15.3], ['wind', 2.8], ['precip', 224.5]])
d8 = dict(zip(['temp', 'wind', 'precip'], [15.3, 2.8, 224.5]))
d9 = dict({'temp': 15.3, 'wind': 2.8}, precip = 224.5)
d1 == d2 == d3 == d4 == d5 == d6 == d7 == d8 == d9
True
上記 d8 で使用されている zip 関数は以下の様に複数のiterableなオブジェクトから一つずつ要素を取り出してタプルを生成する関数です。dict 作成に使用する場合は、keyとvalueの2つのiterableオブジェクトを引数に使用します。
# zip: 複数のiterableなオブジェクトから一つずつ要素を取り出してタプルを生成する関数
print(list(zip(['one', 'two', 'three'], [1, 2, 3])))
for item in zip(('one', 'two', 'three'), (1, 2, 3), ['一', '二', '三']):
print(item)
[(‘one’, 1), (‘two’, 2), (‘three’, 3)]
(‘one’, 1, ‘一’)
(‘two’, 2, ‘二’)
(‘three’, 3, ‘三’)
list(d), tuple(d)
dict に list 関数を適用すると key の list が得られます。同様に dict に tuple を適用すると key の tuple が得られます。
# dict に list や tuple を使うと key の list や tuple が得られる
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
list(d), tuple(d)
([‘温度’, ‘風速’, ‘月間降水量’], (‘温度’, ‘風速’, ‘月間降水量’))
len(d)
dict に len 関数を適用すると 項目(item) の数が得られます。
# dict に len 関数を適用すると 項目(item) の数が得られる
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
len(d)
3
d[key]
導入部でも触れましたが、dict に [key] をつけると該当項目の value を抽出できます。key がない場合は KeyError となります。
d = {'温度':15.3, '風速':2.8, '月間降水量':224.5}
print(d['温度'])
print(d['湿度'])
15.3
get(key[, default])
KeyErrorを回避するには、get メソッドを使用すれば key がない場合は引数の default が、引数がない場合は None が返されます。
d = {'温度':15.3, '風速':2.8, '月間降水量':224.5}
print(d.get('温度'))
print(d.get('湿度'))
15.3
None
d[key] = value, setdefault(key[, default])
これも導入部で触れましたが、d[key] = value で key がある場合は変更、無い場合は追加ができます。(コードはこちら)
setdefault(key[, default]) メソッドは keyがない場合のみにcvデフォルト値が追加されます。
d = {'温度':14.6, '風速':2.9, '月間降水量':198.0}
print(d)
d.setdefault('月間降水量', 0.0) #keyが存在する場合、値はそのまま
print(d)
d.setdefault('積雪量', 0.0) #keyが存在しない場合はdefault値 0.0 が追加される
print(d)
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0, ‘積雪量’: 0.0}
del d[key]
del d[key] で key を削除することができます。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0, '積雪量': 0.0}
print(d)
del d['積雪量']
print(d)
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0, ‘積雪量’: 0.0}
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
items(), keys(), values()
items、keys、values メソッドはそれぞれ(key, value)、key、valueのビューオブジェクトと呼ばれるもの(dict_items, dict_keys, dict_values)を返します。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
print(d.items(), '\n',
d.keys(), '\n',
d.values(), sep = '')
type(d.items()), type(d.keys()), type(d.values())
dict_items([(‘温度’, 14.6), (‘風速’, 2.9), (‘月間降水量’, 198.0)])
dict_keys([‘温度’, ‘風速’, ‘月間降水量’])
dict_values([14.6, 2.9, 198.0])
(dict_items, dict_keys, dict_values)
dict を for 文で使用する場合、通常このビューオブジェクトが使われます。
dict をそのまま for 文で使用すると変数には key が格納されます。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
for i in d:
print(i)
温度
風速
月間降水量
for 文に items メソッドを使用すれば、変数には tuple の (key, value) が格納されます。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
for i in d.items():
print(i)
(‘温度’, 14.6)
(‘風速’, 2.9)
(‘月間降水量’, 198.0)
同様に items メソッドを使って、for文の変数を2つにすれば key と value がそれぞれ格納されます。以下の場合、k, v は (k, v) と同じ tuple です。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
for k, v in d.items():
print(k, v)
温度 14.6
風速 2.9
月間降水量 198.0
keys メソッドは key、values メソッドは value を取り出すことができます。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
for k in d.keys():
print(k)
for v in d.values():
print(v)
温度
風速
月間降水量
14.6
2.9
198.0
key in d, key not in d
dict に in, not in を適用する場合は、key の検索結果が True / False で返されます。
d = {'温度': 21.0, '風速': 2.9, '月間降水量': 198.0}
print('風速' in d, '風力' in d,
'風速' not in d, '風力' not in d)
True False False True
この場合も、ビューオブジェクトを使うことで item や value の検索が可能となります。
d = {'温度': 21.0, '風速': 2.9, '月間降水量': 198.0}
print(('風速', 2.9) in d.items(), ('風速', 2.5) in d.items(),
('風速', 2.9) not in d.items(), ('風速', 2.5) not in d.items())
print('風速' in d.keys(), '風力' in d.keys(),
'風速' not in d.keys(), '風力' not in d.keys())
print(2.9 in d.values(), 2.5 in d.values(),
2.9 not in d.values(), 2.5 not in d.values())
True False False True
True False False True
True False False True
iter(d)
dict も シーケンス型や set と同じく iterable オブジェクトですので、iter 関数で iterator を作成することができます。実際には上記例と同様にビューオブジェクトを使用して iterator を作成します。「 iter(d) は iter(d.keys()) へのショートカット」の通り、dict を直接 iter 関数の引数に入れた場合は、key のみの iterator が返されます。
d = {'温度': 21.0, '風速': 2.9, '月間降水量': 198.0}
it_item, it_key, it_value = iter(d.items()), iter(d.keys()), iter(d.values())
while True:
try:
print(next(it_item), next(it_key), next(it_value))
except StopIteration:
break
(‘温度’, 21.0) 温度 21.0
(‘風速’, 2.9) 風速 2.9
(‘月間降水量’, 198.0) 月間降水量 198.0
iter 関数についてはこちらを参照してください。
reversed(d)
reversed は要素を逆順に取り出すイテレータ( reverse iterator )を返す組込関数です。引数にはビューオブジェクトを使用します。従って reversed(d) は reversed(d.keys()) のショートカットとなります。
d = {'温度': 21.0, '風速': 2.9, '月間降水量': 198.0}
for k, v in reversed(d.items()):
print(k, v)
for k in reversed(d.keys()):
print(k)
for v in reversed(d.values()):
print(v)
月間降水量 198.0
風速 2.9
温度 21.0
月間降水量
風速
温度
198.0
2.9
21.0
clear()
clear は辞書の全ての項目を消去するメソッドです。
d = {'温度': 21.0, '風速': 2.9, '月間降水量': 198.0}
d.clear()
d
{}
copy()
dict は list や set と同じく mutable object なので、複製には copy メソッドが必要です。以下 d2 は = で d1 を代入したもの、d3 は copy メソッドで複製したものです。
d1 = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
d2 = d1
d3 = d1.copy()
d1['温度'] = 21.0 # d1のみ温度を変更
print('d1: ', d1, '\n',
'd2: ', d2, '\n',
'd3: ', d3, sep = '')
d1: {‘温度’: 21.0, ‘風速’: 2.9, ‘月間降水量’: 198.0}
d2: {‘温度’: 21.0, ‘風速’: 2.9, ‘月間降水量’: 198.0}
d3: {‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
d1 の温度を変更すると、= で代入した d2 も変わりますが、copy メソッドで複製した d3 は変更されないことがわかります。
fromkeys(iterable[, value])
fromkeys メソッドは iterable の要素を key として value がデフォルト値の dict を作成するときに使用します。
d = {}
d.fromkeys(['温度', '風速', '月間降水量'], 0.0
{‘温度’: 0.0, ‘風速’: 0.0, ‘月間降水量’: 0.0}
pop(key[, default])
popメソッドは、key が辞書に存在すればその値を辞書から消去して返し、そうでなければ default を返すメソッドです。default が与えらず、かつ key が辞書に存在しいときは KeyError となります。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
print(d)
keys = list(d.keys())
for k in keys:
print(k, d.pop(k), d)
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
温度 14.6 {‘風速’: 2.9, ‘月間降水量’: 198.0}
風速 2.9 {‘月間降水量’: 198.0}
月間降水量 198.0 {}
popitem()
popitem メソッドは項目 (key, value) を辞書から消去して返します。 LIFO (Last In First Out 後入先出)の順序で項目が返却されます。
d = {'温度': 14.6, '風速': 2.9, '月間降水量': 198.0}
print(d)
while d:
print(d.popitem(), d)
{‘温度’: 14.6, ‘風速’: 2.9, ‘月間降水量’: 198.0}
(‘月間降水量’, 198.0) {‘温度’: 14.6, ‘風速’: 2.9}
(‘風速’, 2.9) {‘温度’: 14.6}
(‘温度’, 14.6) {}
演算子 d | other
dict に使える演算子は和集合を意味する | と、その累算代入演算子の |= です 。
d1 = {'温度': 14.6, '風速': 2.9}
d2 = {'風速': 3.0, '月間降水量': 198.0}
d3 = d1 | d2
d3
{‘温度’: 14.6, ‘風速’: 3.0, ‘月間降水量’: 198.0}
key が同じで value が異なる場合(上記の’風速’)| の後の other の値が優先されます。
ビューオブジェクトを使用すると set (集合型) の演算子を使用できますが、型を dict に戻すためには dict 関数を使用する必要があります。
d1 = {'温度': 14.6, '風速': 2.9}
d2 = {'風速': 2.9, '月間降水量': 198.0}
d3 = dict(d1.items() & d2.items())
d3
{‘風速’: 2.9}
この場合は、(key, value) をセットとして演算しますので d2 の’風速’を 3.0 とすると、ビューオブジェクトの積集合は空集合となり、d3 は {} となります。
累算代入演算子 d |= other
累算代入演算子の |= を使う場合も key が同じで value が異なる場合、other の値に更新されます。
d1 = {'温度': 14.6, '風速': 2.9}
d2 = {'風速': 3.0, '月間降水量': 198.0}
d1 |= d2
d1
{‘温度’: 14.6, ‘風速’: 3.0, ‘月間降水量’: 198.0}
update([other])
update メソッドは上記の |= と同じく辞書の内容を other のキーと値で更新します。既存のキーは上書きされます。
d1 = {'温度': 14.6, '風速': 2.9}
d2 = {'風速': 3.0, '月間降水量': 198.0}
d1.update(d2)
d1
{‘温度’: 14.6, ‘風速’: 3.0, ‘月間降水量’: 198.0}
すでにご存知かと思いますが、更新のメソッドを以下の様に代入してはいけません。「戻り値は None」はこの出力の None を指します。
d1 = {'温度': 14.6, '風速': 2.9}
d2 = {'風速': 3.0, '月間降水量': 198.0}
d1 = d1.update(d2)
print(d1)
None
練習問題_5_3 東京都の天気①
以下のデータは、東京都の2022年4月の各観測所の dict データです。各項目が dict のネストになっています。
wt_2204 = {'小河内':{'降水量':157.0, '気温':11.9, '風速':1.1, '日照時間':164.6},
'青梅':{'降水量':177.5, '気温':14.3, '風速':1.3, '日照時間':172.4},
'練馬':{'降水量':195.0, '気温':15.0, '風速':1.6, '日照時間':168.9},
'八王子':{'降水量':198.0, '気温':14.6, '風速':2.9, '日照時間':172.4},
'府中':{'降水量':217.5, '気温':14.8, '風速':1.8, '日照時間':166.2},
'東京':{'降水量':224.5, '気温':15.3, '風速':2.8, '日照時間':169.5}}
以上のデータに、各観測項目毎の各地点の平均値と、観測地点と観測項目の各 tuple のdict型3項目を追加して、以下のように wt_2204 を更新してください。
{‘小河内’: {‘降水量’: 157.0, ‘気温’: 11.9, ‘風速’: 1.1, ‘日照時間’: 164.6},
‘青梅’: {‘降水量’: 177.5, ‘気温’: 14.3, ‘風速’: 1.3, ‘日照時間’: 172.4},
‘練馬’: {‘降水量’: 195.0, ‘気温’: 15.0, ‘風速’: 1.6, ‘日照時間’: 168.9},
‘八王子’: {‘降水量’: 198.0, ‘気温’: 14.6, ‘風速’: 2.9, ‘日照時間’: 172.4},
‘府中’: {‘降水量’: 217.5, ‘気温’: 14.8, ‘風速’: 1.8, ‘日照時間’: 166.2},
‘東京’: {‘降水量’: 224.5, ‘気温’: 15.3, ‘風速’: 2.8, ‘日照時間’: 169.5},
‘平均’: {‘降水量’: 194.92, ‘気温’: 14.32, ‘風速’: 1.92, ‘日照時間’: 169.0},
‘観測地点’: (‘小河内’, ‘青梅’, ‘練馬’, ‘八王子’, ‘府中’, ‘東京’),
‘観測項目’: (‘降水量’, ‘気温’, ‘風速’, ‘日照時間’)}
この問題では、各観測地点の観測項目は全て同じであることを前提とします。
練習問題_5_4 東京都の天気②
今度のデータは、上記①に羽田と世田谷が加わっています。
wt2_2204 = {'小河内':{'降水量':157.0, '気温':11.9, '風速':1.1, '日照時間':164.6},
'青梅':{'降水量':177.5, '気温':14.3, '風速':1.3, '日照時間':172.4},
'練馬':{'降水量':195.0, '気温':15.0, '風速':1.6, '日照時間':168.9},
'八王子':{'降水量':198.0, '気温':14.6, '風速':2.9, '日照時間':172.4},
'府中':{'降水量':217.5, '気温':14.8, '風速':1.8, '日照時間':166.2},
'東京':{'降水量':224.5, '気温':15.3, '風速':2.8, '日照時間':169.5},
'羽田':{'降水量':187.5, '気温':15.4, '風速':5.6},
'世田谷':{'降水量':218.0}}
羽田のデータには日照時間がなく、世田谷は降水量のデータのみとなっています。各観測項目毎の各地点の平均値と、観測地点と観測項目の各 tuple のdict型3項目を追加して、以下のように wt2_2204 を更新してください。
{‘小河内’: {‘降水量’: 157.0, ‘気温’: 11.9, ‘風速’: 1.1, ‘日照時間’: 164.6},
‘青梅’: {‘降水量’: 177.5, ‘気温’: 14.3, ‘風速’: 1.3, ‘日照時間’: 172.4},
‘練馬’: {‘降水量’: 195.0, ‘気温’: 15.0, ‘風速’: 1.6, ‘日照時間’: 168.9},
‘八王子’: {‘降水量’: 198.0, ‘気温’: 14.6, ‘風速’: 2.9, ‘日照時間’: 172.4},
‘府中’: {‘降水量’: 217.5, ‘気温’: 14.8, ‘風速’: 1.8, ‘日照時間’: 166.2},
‘東京’: {‘降水量’: 224.5, ‘気温’: 15.3, ‘風速’: 2.8, ‘日照時間’: 169.5},
‘羽田’: {‘降水量’: 187.5, ‘気温’: 15.4, ‘風速’: 5.6},
‘世田谷’: {‘降水量’: 218.0},
‘平均’: {‘降水量’: 196.88, ‘気温’: 14.47, ‘風速’: 2.44, ‘日照時間’: 169.0},
‘観測地点’: (‘小河内’, ‘青梅’, ‘練馬’, ‘八王子’, ‘府中’, ‘東京’, ‘羽田’, ‘世田谷’),
‘観測項目’: (‘降水量’, ‘気温’, ‘風速’, ‘日照時間’)}
この問題では、各観測地点の観測項目は事前には何が含まれているのか分からないことを前提とします。平均は項目が存在する観測地点の平均を取ってください。例えば日照時間の場合は、データがない羽田と世田谷以外の観測値の平均をとります。