プログラミングにおいて、最も重要と言えるデータ構造が今回紹介するディクショナリ(連想配列と呼ぶことも多い)だ。

通常の配列では、インデックス番号を整数として指定して要素を取り出すが、ディクショナリでは整数以外のデータをキーとして、それに該当する値(バリュー)を取り出すことができる。

ディクショナリの定義と参照

まず新たにディクショナリを作るときは、中括弧を使い、キー・バリュー形式で定義する。

empty_dict = {} # 空のディクショナリ

d1 = {
    'name': 'taro',
    'age': 20,
    'score': {
        'kokugo': 80,
        'sugaku': 95
    }
}

d1 # {'name': 'taro', 'age': 20, 'score': {'kokugo': 80, 'sugaku': 95}}

参照や要素の追加などは、リストやタプルと同じ操作で行うことができる。

d1 # {'name': 'taro', 'age': 20, 'score': {'kokugo': 80, 'sugaku': 95}}

d1['name'] # 'taro'
d1['score']['kokugo'] # 80

d1['score']['rika'] = 75
d1['score'] # {'kokugo': 80, 'sugaku': 95, 'rika': 75}

特定のキーが存在するかを調べる

リストやタプルでは特定の値が存在するかを調べることが可能だが、ディクショナリでは特定のキーが入っているかを調べることができる。

d1 # {'name': 'taro', 'age': 20, 'score': {'kokugo': 80, 'sugaku': 95}}

'score' in d1 # True

ディクショナリの要素を削除する

ディクショナリから要素を削除する方法は二つある。

まず、delキーワードを使う方法だ。
delに続けて特定の要素を指定することで削除することができる。

d1 # {'name': 'taro', 'age': 20, 'score': {'kokugo': 80, 'sugaku': 95}}

del d1['age']
d1 # {'name': 'taro', 'score': {'kokugo': 80, 'sugaku': 95}}

次にpopメソッドを使う方法もあるが、これは要素を削除すると同時に、削除した要素を取り出すことができる。
以下のようにpopメソッドの引数にキーを指定すると、指定のキーに該当する値が取得され、同時に指定のキー・バリューのペアが削除される。

d1 # {'name': 'taro', 'age': 20, 'score': {'kokugo': 80, 'sugaku': 95}}

age = d1.pop('age')
age # 20
d1 # {'name': 'taro', 'score': {'kokugo': 80, 'sugaku': 95}}

ディクショナリをマージする

updateメソッドを使うことで、既存のディクショナリと別のディクショナリをマージ(結合)することができる。

d1 # {'name': 'taro', 'age': 20, 'score': {'kokugo': 80, 'sugaku': 95}}

d1.update(
    {
        'name': 'jiro',
        'pref': 'Osaka'
    }
)

d1
"""
{'name': 'jiro',
 'age': 20,
 'score': {'kokugo': 80, 'sugaku': 95},
 'pref': 'Osaka'}
"""

引数に指定したディクショナリと同じキーがある場合は、既存の値は上書きされ、その他の値はそのまま保持される。

ディクショナリのデフォルト値

あるディクショナリに特定のキーが含まれていれば、それに該当する値を変数にセットし、キーが含まれていなければ特定の値をセットするといった処理を行う場合、通常考えられるのは以下のようなコードだろう。

if 'age' in d1:
    age = d1['age']
else:
    age = 18

ディクショナリのgetメソッドは、このようなコードを簡単に書けるようにしてくれる。

第一引数にキーを指定し、ディクショナリ内にキーが見つかれば該当する値を、見つからなければ第二引数に指定したデフォルト値を返す。

age = d1.get('age', 18)

キーの型はハッシュ可能な型でなければならない

ディクショナリの値(バリュー)は、どのようなデータ型でも代入することができるが、キーには使用できるデータ型というものがある。

キーは必ずハッシュ可能なオブジェクトでなければならないのだ。

どういうことかというと、変更不可能なタプルや、int、float、stringなどのスカラー値でなければならない。
リストなどをキーとすることはできないのだ。

オブジェクトがハッシュ可能であるかを確認するにはhash関数を使うと良い。

hash('string') # 2252006465005836270
hash(123) # 123
hash((1, 2)) # 3713081631934410656
hash([1, 2]) # リストはエラーになる!!

ディクショナリは読みやすくコードの管理がしやすい

リストでは複数の値を一つの配列としてまとめて管理することができるが、その管理方法はインデックス番号によるものなので、要素の管理には不向きである。

クラスメイトと各教科のテストの点数を多次元のリストで管理する場合、「0番の{0}の点数は80点、{1}の点数は90点」といった具合で、人間が理解するには難解だ。

ディクショナリはキーに意味を持たせることができるので「taroさんの出席番号は1番、国語の点数は80点、数学の点数は90点」などと、理解しやすいデータ構造で管理することができる。

記事冒頭でも記述したとおり、プログラミングにおいて最重要と言えるデータ構造なので、ここで紹介した基本の操作方法はしっかり理解しておきたい。