Python 入門

Python 辞書 (Dictionary)

辞書(Dictionaries)は、キー・バリューペア(key-value pairs)を使用してデータを格納・検索する手法を提供します。
数値インデックスに依存して要素にアクセスするリストやタプルとは異なり、辞書は「キー」(ほとんどすべてのイミュータブルなデータ型が使用可能)をガイドとして使用します。これにより、より直感的かつ効率的なデータ管理が可能となり、現実世界のオブジェクト、設定情報、さまざまなマッピング関係を表現する際に非常に柔軟に機能します。

1. 辞書の理解:キー・バリュー構造

本質的に、辞書はキー・バリューペアの集合です。辞書内の各「キー (key)」は一意であり、特定の「値 (value)」に関連付けられています。この関連付けにより、特定のキーを通じて対応する値を素早く見つけることができます。

1.1 キー (Keys) と 値 (Values)

  • キー (Keys): キーは、辞書内の値にアクセスするための識別子です。これらは、文字列、数値(整数、浮動小数点数)、タプルなどのイミュータブル(immutable/不変)なデータ型である必要があります。この不変性は極めて重要です。なぜなら、Python は内部的にキーを使用してハッシュ値 (hash value)を計算し、関連する値の位置を特定するからです。もしキーがミュータブル(変更可能)であれば、ハッシュ値が変わってしまう可能性があり、データを正しく検索できなくなります。
  • 値 (Values): 一方で、値はどのようなデータ型でも構いません。これには、リストや他の辞書といったミュータブルな型も含まれます。この柔軟性により、極めて複雑でネストされたデータ構造を辞書内に格納することが可能になります。

2. 辞書の作成

辞書を作成するには、いくつかの一般的な方法があります。

  1. 波括弧 {} を使用する: 最も一般的な方法です。キーと値をコロン : で区切り、各ペアをカンマ , で区切って波括弧内に配置します。
  2. dict() コンストラクタを使用する: キーワード引数、またはキー・バリューペアのシーケンス(タプルを含むリストなど)を使用して辞書を作成できます。
# 1. 波括弧を使用した辞書の作成
student = {
    "name": "Alice",
    "age": 20,
    "major": "Computer Science"
}

# 2. dict() コンストラクタとキーワード引数を使用した作成
student_2 = dict(name="Bob", age=22, major="Engineering")

# 3. dict() コンストラクタとタプルのリストを使用した作成
student_3 = dict([("name", "Charlie"), ("age", 19), ("major", "Mathematics")])

print(student)
print(student_2)
print(student_3)

3. 辞書内の値へのアクセス

対応するキーを角括弧 [] の中に入れることで、辞書内の値にアクセスできます。

student = {
    "name": "Alice",
    "age": 20,
    "major": "Computer Science"
}

print(student["name"])  # 出力: Alice
print(student["age"])   # 出力: 20

安全なアクセスのテクニック: 辞書に存在しないキーにアクセスしようとすると、Python は KeyError をスローします。プログラムのクラッシュを避けるために、get() メソッドの使用を推奨します。キーが見つからない場合、get() はデフォルトで None を返します(または任意のデフォルト値を指定できます)。

student = {
    "name": "Alice",
    "age": 20,
    "major": "Computer Science"
}

print(student.get("name"))            # 出力: Alice
print(student.get("city"))            # キーが存在しないため、出力: None
print(student.get("city", "Unknown")) # キーが存在しない場合、指定したデフォルト値を返す、出力: Unknown

4. 辞書の修正(追加・変更・削除)

辞書はミュータブル (mutable) です。つまり、辞書の作成後にキー・バリューペアを自由に追加、削除、または修正できます。

  • 新しいキー・バリューペアの追加: 存在しない新しいキーを角括弧で指定し、値を代入するだけです。
  • 既存の値を修正: 既存のキーを指定し、新しい値を代入します。
  • キー・バリューペアの削除: del キーワードを使用して直接削除するか、pop() メソッド(削除と同時にその値を取得できる)を使用します。
student = {
    "name": "Alice",
    "age": 20,
    "major": "Computer Science"
}

# 新しいキー・バリューペアの追加
student["city"] = "New York"
print(student) # 出力: {'name': 'Alice', 'age': 20, 'major': 'Computer Science', 'city': 'New York'}

# 既存の値を修正
student["age"] = 21
print(student) # 出力: {'name': 'Alice', 'age': 21, 'major': 'Computer Science', 'city': 'New York'}

# del キーワードを使用した削除
del student["city"]
print(student) # 出力: {'name': 'Alice', 'age': 21, 'major': 'Computer Science'}

# pop() メソッドを使用した削除と値の取得
major = student.pop("major")
print(student) # 出力: {'name': 'Alice', 'age': 21}
print(major)   # 出力: Computer Science

5. 辞書操作と一般的な組み込みメソッド

Python は、キーの存在確認、すべてのキーや値の取得、辞書の結合など、辞書を操作するための複数のメソッドを提供しています。

  • keys(): 辞書内のすべてのキーを含むビューオブジェクトを返します。
  • values(): 辞書内のすべての値を含むビューオブジェクトを返します。
  • items(): すべてのキー・バリューペア(タプル形式)を含むビューオブジェクトを返します。
  • update(other_dict): 別の辞書のペアを現在の辞書に更新します。キーが存在すれば値を更新し、なければ追加します。
  • clear(): すべてのペアを削除し、空の辞書にします。
student = {
    "name": "Alice",
    "age": 20,
    "major": "Computer Science"
}

# すべてのキーを取得
keys = student.keys()
print(keys) # 出力: dict_keys(['name', 'age', 'major'])

# すべての値を取得
values = student.values()
print(values) # 出力: dict_values(['Alice', 20, 'Computer Science'])

# すべてのペアを取得
items = student.items()
print(items) # 出力: dict_items([('name', 'Alice'), ('age', 20), ('major', 'Computer Science')])

# 辞書の更新
student.update({"city": "New York", "gpa": 3.8})
print(student) # 出力: {'name': 'Alice', 'age': 20, 'major': 'Computer Science', 'city': 'New York', 'gpa': 3.8}

# 辞書のクリア
student.clear()
print(student) # 出力: {}

6. 辞書内包表記

リスト内包表記と同様に、辞書内包表記は辞書を簡潔に生成する手法を提供します。イテラブルなオブジェクトからキー・バリューペアを生成し、条件によるフィルタリングも可能です。

基本構文: {key: value for item in iterable if condition}

# 数値とその平方をマッピングする辞書を作成
squares = {x: x**2 for x in range(5)}
print(squares) # 出力: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 偶数とその平方のみを含む辞書を作成
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares) # 出力: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

7. 実践ケースとデモンストレーション

辞書の用途は極めて広く、さまざまなデータ構造を表現できます。以下にいくつかの実践例を挙げます。

7.1 設定ファイルの表現

辞書はアプリケーションの設定(構成情報)を格納する際によく使われます。各キーが設定項目名、値がその内容を表します。

config = {
    "database_host": "localhost",
    "database_port": 5432,
    "debug_mode": True,
    "log_level": "INFO"
}

print(f"データベースホスト: {config['database_host']}")
print(f"デバッグモード: {config['debug_mode']}")

7.2 ユーザープロフィールの保存

ユーザー属性(名前、メールアドレスなど)を管理するために辞書を使用できます。

user_profile = {
    "username": "johndoe",
    "email": "[email protected]",
    "age": 30,
    "city": "San Francisco"
}

print(f"ユーザー名: {user_profile['username']}")
print(f"メール: {user_profile['email']}")

7.3 シンプルな電話帳の実装

辞書は電話帳の実装に最適です。キーを名前、値を電話番号として扱います。

phonebook = {
    "Alice": "123-456-7890",
    "Bob": "987-654-3210",
    "Charlie": "555-123-4567"
}

print(f"Alice の番号: {phonebook['Alice']}")

# 新しい連絡先の追加
phonebook["David"] = "111-222-3333"

# 連絡先の削除
del phonebook["Bob"]

print(phonebook)