メインコンテンツへスキップ
Lesson2 / 6

辞書の要素にアクセスする

目次

1. このレッスンで学ぶこと

  • 辞書の値を取得する方法
  • 安全なアクセス方法
  • ネストした辞書へのアクセス
  • デフォルト値の活用

2. アクセス方法とは

辞書へのアクセス方法は、キーや値を取り出すための複数の手段です。直接アクセス、安全なアクセス、ネスト対応など、状況に応じた方法を選択することが重要です。

アクセス方法使用場面利点注意点
ブラケット記法キーが確実に存在シンプルKeyErrorが発生
get()メソッド不確定なキー安全キー不在時はNone
in演算子存在確認明確アクセス前チェック

主な特徴:

  • ブラケット記法は高速だが存在確認が必要
  • get()はキーなし時のデフォルト値を指定可能
  • ネストした辞書は各階層で段階的にアクセス
  • in演算子でキーの存在を事前確認できる

簡単なコード例:

Python
user = {"name": "太郎", "age": 25}

# ブラケット記法
print(user["name"])        # 太郎

# get()メソッド(安全)
email = user.get("email")  # None
phone = user.get("phone", "未登録")  # 未登録

# 存在確認
if "age" in user:
    print(user["age"])     # 25

3. なぜアクセス方法を学ぶのか?

辞書からデータを取り出す方法は複数あり、状況に応じて使い分けが必要です。

Python
user = {"name": "太郎", "age": 25}

# 存在するキー
print(user["name"])  # OK

# 存在しないキー
# print(user["email"])  # エラー!

# 安全な方法
print(user.get("email", "未登録"))  # OK

適切なアクセス方法を選ぶことで、エラーを防げます。

💡 豆知識: Pythonの辞書アクセスは平均O(1)の時間複雑度で非常に高速です。100万個の要素があっても、キーで直接アクセスできるため、リストの検索(O(n))よりもはるかに効率的です。


4. ブラケット記法

基本的なアクセス

機能: [キー]で値を直接取得します。

書き方:

Python
= 辞書[キー]

用途: キーが確実に存在する場合

注意点: 存在しないキーはKeyErrorが発生

Python
# 基本的なアクセス
person = {
    "name": "山田太郎",
    "age": 30,
    "city": "東京",
    "job": "エンジニア"
}

# 値の取得
print(f"名前: {person['name']}")
print(f"年齢: {person['age']}歳")
print(f"住所: {person['city']}")
print(f"職業: {person['job']}")

# 存在しないキー(エラー)
try:
    print(person['email'])
except KeyError as e:
    print(f"エラー: キー {e} が見つかりません")

実行結果:

名前: 山田太郎
年齢: 30歳
住所: 東京
職業: エンジニア
エラー: キー 'email' が見つかりません

ブラケット記法の使い所

Python
# 設定ファイルの読み込み(必須項目)
config = {
    "host": "localhost",
    "port": 5432,
    "database": "mydb"
}

# 必須項目は直接アクセスOK
# (存在しない場合はエラーにすべき)
host = config["host"]
port = config["port"]
database = config["database"]

print(f"接続先: {host}:{port}/{database}")

# データベース接続(疑似コード)
def connect_database(config):
    # 必須項目が無ければエラーで止まる
    return f"Connected to {config['host']}:{config['port']}"

print(connect_database(config))

実行結果:

接続先: localhost:5432/mydb
Connected to localhost:5432

5. get()メソッド

安全なアクセス

機能: キーが存在しない場合にデフォルト値を返します。

書き方:

Python
= 辞書.get(キー)
= 辞書.get(キー, デフォルト値)

用途: オプション項目、存在が不確定なキー

注意点: デフォルト値を指定しないとNoneを返す

Python
user = {
    "username": "yamada",
    "email": "yamada@example.com",
    "verified": True
}

# get()の基本
print(f"ユーザー名: {user.get('username')}")

# 存在しないキー(Noneを返す)
phone = user.get('phone')
print(f"電話番号: {phone}")

# デフォルト値を指定
phone = user.get('phone', '未登録')
print(f"電話番号: {phone}")

address = user.get('address', '未設定')
print(f"住所: {address}")

実行結果:

ユーザー名: yamada
電話番号: None
電話番号: 未登録
住所: 未設定

get()の実践的な使い方

Python
# API応答の処理
api_response = {
    "status": "success",
    "data": {
        "id": 123,
        "name": "商品A"
    }
}

# オプショナルなフィールド
status = api_response.get("status", "unknown")
message = api_response.get("message", "メッセージなし")
error = api_response.get("error", "エラーなし")

print(f"ステータス: {status}")
print(f"メッセージ: {message}")
print(f"エラー: {error}")

# データの取得
data = api_response.get("data", {})
if data:
    print(f"ID: {data.get('id')}")
    print(f"名前: {data.get('name')}")

実行結果:

ステータス: success
メッセージ: メッセージなし
エラー: エラーなし
ID: 123
名前: 商品A

6. ネストした辞書へのアクセス

多階層のデータ

機能: 辞書の中の辞書にアクセスします。

書き方:

Python
= 辞書[キー1][キー2][キー3]

用途: JSON形式のデータ、複雑な設定

注意点: 途中のキーが存在しないとエラー

Python
# ネストした辞書
company = {
    "name": "Tech Corp",
    "employees": {
        "engineering": {
            "manager": "山田太郎",
            "members": ["佐藤", "鈴木", "田中"],
            "count": 3
        },
        "sales": {
            "manager": "伊藤花子",
            "members": ["高橋", "渡辺"],
            "count": 2
        }
    },
    "address": {
        "city": "東京",
        "zipcode": "100-0001"
    }
}

# 多階層アクセス
print(f"会社名: {company['name']}")
print(f"エンジニアリング部長: {company['employees']['engineering']['manager']}")
print(f"営業部員数: {company['employees']['sales']['count']}人")
print(f"所在地: {company['address']['city']}")

# メンバーリストの取得
eng_members = company['employees']['engineering']['members']
print(f"エンジニア: {', '.join(eng_members)}")

実行結果:

会社名: Tech Corp
エンジニアリング部長: 山田太郎
営業部員数: 2人
所在地: 東京
エンジニア: 佐藤, 鈴木, 田中

安全なネストアクセス

Python
# 複雑なJSON風データ
data = {
    "user": {
        "profile": {
            "name": "太郎",
            "age": 25
        }
    }
}

# 危険なアクセス(途中のキーが無いとエラー)
# email = data['user']['profile']['email']  # KeyError

# 安全なアクセス方法1: get()を連鎖
user = data.get('user', {})
profile = user.get('profile', {})
email = profile.get('email', '未登録')
print(f"メール: {email}")

# 安全なアクセス方法2: 存在確認
if 'user' in data and 'profile' in data['user']:
    profile = data['user']['profile']
    name = profile.get('name', '不明')
    age = profile.get('age', 0)
    print(f"名前: {name}, 年齢: {age}歳")

# 安全なアクセス方法3: try-except
try:
    city = data['user']['profile']['address']['city']
except KeyError:
    city = '未設定'
print(f"都市: {city}")

実行結果:

メール: 未登録
名前: 太郎, 年齢: 25歳
都市: 未設定

7. 複数の値を一度に取得

複数のget()

Python
settings = {
    "theme": "dark",
    "language": "ja",
    "notifications": True
}

# 個別に取得
theme = settings.get('theme', 'light')
language = settings.get('language', 'en')
notifications = settings.get('notifications', False)
font_size = settings.get('font_size', 14)

print(f"テーマ: {theme}")
print(f"言語: {language}")
print(f"通知: {notifications}")
print(f"フォントサイズ: {font_size}")

実行結果:

テーマ: dark
言語: ja
通知: True
フォントサイズ: 14

デフォルト値を辞書で管理

Python
# ユーザー設定
user_settings = {
    "theme": "dark",
    "language": "ja"
}

# デフォルト設定
default_settings = {
    "theme": "light",
    "language": "en",
    "font_size": 14,
    "notifications": True,
    "auto_save": True
}

# デフォルト値とマージ
def get_setting(key):
    return user_settings.get(key, default_settings.get(key))

print("=== 最終設定 ===")
for key in default_settings.keys():
    value = get_setting(key)
    print(f"{key}: {value}")

実行結果:

=== 最終設定 ===
theme: dark
language: ja
font_size: 14
notifications: True
auto_save: True

8. キーの存在確認

in演算子

機能: キーが辞書に存在するか確認します。

書き方:

Python
if キー in 辞書:
    # 存在する

用途: アクセス前の事前チェック

注意点: 値の存在ではなく、キーの存在を確認

Python
inventory = {
    "apple": 10,
    "banana": 5,
    "orange": 0  # 在庫0でもキーは存在
}

# キーの存在確認
if "apple" in inventory:
    print(f"りんご在庫: {inventory['apple']}個")

if "grape" not in inventory:
    print("ぶどうは取り扱いなし")

# 在庫があるかチェック(値も確認)
def has_stock(item):
    if item in inventory and inventory[item] > 0:
        return True
    return False

print(f"りんご在庫あり: {has_stock('apple')}")
print(f"オレンジ在庫あり: {has_stock('orange')}")
print(f"ぶどう在庫あり: {has_stock('grape')}")

実行結果:

りんご在庫: 10個
ぶどうは取り扱いなし
りんご在庫あり: True
オレンジ在庫あり: False
ぶどう在庫あり: False

keys(), values(), items()

Python
user = {
    "id": 1001,
    "name": "太郎",
    "email": "taro@example.com",
    "active": True
}

# 全てのキーを取得
print("=== キー一覧 ===")
for key in user.keys():
    print(f"  {key}")

# 全ての値を取得
print("\n=== 値一覧 ===")
for value in user.values():
    print(f"  {value}")

# キーと値のペアを取得
print("\n=== キーと値 ===")
for key, value in user.items():
    print(f"  {key}: {value}")

# キーの存在確認(別の方法)
if "email" in user.keys():
    print(f"\nメールアドレス: {user['email']}")

実行結果:

=== キー一覧 ===
  id
  name
  email
  active

=== 値一覧 ===
  1001
  太郎
  taro@example.com
  True

=== キーと値 ===
  id: 1001
  name: 太郎
  email: taro@example.com
  active: True

メールアドレス: taro@example.com

9. 具体例

例1: 設定の取得と検証

Python
# アプリケーション設定
config = {
    "host": "localhost",
    "port": 8000,
    "debug": True
}

# 必須項目のチェック
required_keys = ["host", "port"]
missing_keys = []

for key in required_keys:
    if key not in config:
        missing_keys.append(key)

if missing_keys:
    print(f"エラー: 必須項目が不足: {missing_keys}")
else:
    print("設定OK")

# オプション項目の取得
debug = config.get("debug", False)
timeout = config.get("timeout", 30)
max_connections = config.get("max_connections", 100)

print(f"\n=== サーバー設定 ===")
print(f"ホスト: {config['host']}")
print(f"ポート: {config['port']}")
print(f"デバッグ: {debug}")
print(f"タイムアウト: {timeout}秒")
print(f"最大接続数: {max_connections}")

実行結果:

設定OK

=== サーバー設定 ===
ホスト: localhost
ポート: 8000
デバッグ: True
タイムアウト: 30秒
最大接続数: 100

例2: ユーザープロフィールの表示

Python
# ユーザーデータ
users = {
    "user001": {
        "name": "山田太郎",
        "email": "yamada@example.com",
        "age": 28,
        "premium": True
    },
    "user002": {
        "name": "佐藤花子",
        "email": "sato@example.com",
        "age": 35
        # premiumフィールドなし
    }
}

# プロフィール表示関数
def display_profile(user_id):
    if user_id not in users:
        print(f"ユーザー {user_id} が見つかりません")
        return

    user = users[user_id]
    name = user.get('name', '名無し')
    email = user.get('email', '未登録')
    age = user.get('age', '不明')
    premium = user.get('premium', False)

    print(f"=== {user_id} ===")
    print(f"名前: {name}")
    print(f"メール: {email}")
    print(f"年齢: {age}歳")
    print(f"プレミアム会員: {'はい' if premium else 'いいえ'}")
    print()

# 表示
display_profile("user001")
display_profile("user002")
display_profile("user999")

実行結果:

=== user001 ===
名前: 山田太郎
メール: yamada@example.com
年齢: 28歳
プレミアム会員: はい

=== user002 ===
名前: 佐藤花子
メール: sato@example.com
年齢: 35歳
プレミアム会員: いいえ

ユーザー user999 が見つかりません

例3: JSONライクなデータの解析

Python
# API応答(JSON風)
response = {
    "status": "success",
    "data": {
        "product": {
            "id": 12345,
            "name": "ノートPC",
            "price": 98000,
            "specs": {
                "cpu": "Core i7",
                "ram": "16GB",
                "storage": "512GB SSD"
            },
            "reviews": {
                "average": 4.5,
                "count": 128
            }
        }
    }
}

# 安全なデータ抽出
status = response.get('status', 'unknown')
print(f"ステータス: {status}")

data = response.get('data', {})
product = data.get('product', {})

if product:
    print(f"\n=== 商品情報 ===")
    print(f"商品ID: {product.get('id', 'N/A')}")
    print(f"商品名: {product.get('name', '不明')}")
    print(f"価格: {product.get('price', 0):,}円")

    # スペック
    specs = product.get('specs', {})
    if specs:
        print(f"\n=== スペック ===")
        print(f"CPU: {specs.get('cpu', '不明')}")
        print(f"メモリ: {specs.get('ram', '不明')}")
        print(f"ストレージ: {specs.get('storage', '不明')}")

    # レビュー
    reviews = product.get('reviews', {})
    if reviews:
        avg = reviews.get('average', 0)
        count = reviews.get('count', 0)
        print(f"\n=== レビュー ===")
        print(f"平均評価: {avg}/5.0 ({count}件)")

実行結果:

ステータス: success

=== 商品情報 ===
商品ID: 12345
商品名: ノートPC
価格: 98,000円

=== スペック ===
CPU: Core i7
メモリ: 16GB
ストレージ: 512GB SSD

=== レビュー ===
平均評価: 4.5/5.0 (128件)

10. 練習問題

問題1(基礎)⭐☆☆

以下のユーザー辞書から、nameageを取得して表示してください。emailはデフォルト値「未登録」で取得してください。

Python
user = {
    "name": "山田太郎",
    "age": 30,
    "city": "東京"
}
💡 ヒント
  • 存在するキーはブラケット記法で取得
  • 存在しないキーはget()メソッドでデフォルト値を指定
✅ 解答例
Python
user = {
    "name": "山田太郎",
    "age": 30,
    "city": "東京"
}

# 存在するキーを取得
name = user["name"]
age = user["age"]

# 存在しないキーをデフォルト値で取得
email = user.get("email", "未登録")

print(f"名前: {name}")
print(f"年齢: {age}歳")
print(f"メール: {email}")

実行結果:

名前: 山田太郎
年齢: 30歳
メール: 未登録

解説: 存在するキーは[]で直接アクセスし、存在しないキーはget()メソッドでデフォルト値を指定します。


問題2(基礎)⭐☆☆

以下のネストした辞書から、商品名と価格を安全に取得して表示してください。

Python
response = {
    "status": "success",
    "data": {
        "product": {
            "name": "ノートPC",
            "price": 98000
        }
    }
}
💡 ヒント
  • 各階層でget()メソッドを使う
  • ネストした辞書もget()でデフォルト値を{}にする
✅ 解答例
Python
response = {
    "status": "success",
    "data": {
        "product": {
            "name": "ノートPC",
            "price": 98000
        }
    }
}

# 安全にネストした辞書にアクセス
data = response.get("data", {})
product = data.get("product", {})
name = product.get("name", "不明")
price = product.get("price", 0)

print(f"商品名: {name}")
print(f"価格: {price:,}円")

実行結果:

商品名: ノートPC
価格: 98,000円

解説: 各階層でget()を使い、存在しない場合のデフォルト値を設定することで、KeyErrorを回避できます。


問題3(応用)⭐⭐☆

以下のAPI応答から、全てのユーザーの名前とメールアドレスを取得して表示してください。メールアドレスが存在しない場合は「未登録」と表示してください。

Python
api_response = {
    "users": [
        {"id": 1, "name": "太郎", "email": "taro@example.com"},
        {"id": 2, "name": "花子"},
        {"id": 3, "name": "次郎", "email": "jiro@example.com"}
    ]
}
💡 ヒント
  1. usersキーから配列を取得
  2. for文でループ処理
  3. 各ユーザーからnameemailを取得(emailget()でデフォルト値)
✅ 解答例
Python
api_response = {
    "users": [
        {"id": 1, "name": "太郎", "email": "taro@example.com"},
        {"id": 2, "name": "花子"},
        {"id": 3, "name": "次郎", "email": "jiro@example.com"}
    ]
}

# usersリストを取得
users = api_response.get("users", [])

print("=== ユーザー一覧 ===")
for user in users:
    name = user.get("name", "不明")
    email = user.get("email", "未登録")
    print(f"{name}: {email}")

実行結果:

=== ユーザー一覧 ===
太郎: taro@example.com
花子: 未登録
次郎: jiro@example.com

解説: リストをループで処理しながら、各辞書からget()メソッドで安全にデータを取得します。存在しないキーはデフォルト値で補完されます。


11. まとめ

このレッスンでは、辞書の要素アクセス方法を学びました。

  • dict[key]get() の違いを理解して使い分けられます。
  • 存在しないキーへのアクセス時の挙動を確認しました。
  • キー存在チェックを組み合わせて安全に値取得できます。
  • 値参照と条件分岐を組み合わせた実装を実践できました。
  • 例外を避けるアクセス設計が安定したコードにつながります。