Pythonで辞書(dict)に新しい項目を追加するには、複数の方法があります。この記事では、状況に応じた最適な方法を解説します。
辞書への項目追加方法の比較
| 方法 | 用途 | 元の辞書 | Python |
|---|---|---|---|
dict[key] = value | 1項目追加 | 変更される | 全バージョン |
update() | 複数項目追加 | 変更される | 全バージョン |
setdefault() | 存在しない場合のみ追加 | 変更される | 全バージョン |
{**dict1, **dict2} | 辞書のマージ | 変更されない | 3.5+ |
dict1 | dict2 | 辞書のマージ | 変更されない | 3.9+ |
dict1 |= dict2 | 辞書のマージ(更新) | 変更される | 3.9+ |
キーと値を直接代入する方法
最もシンプルな方法は、キーと値を直接代入することです。
# 基本的な代入
my_dict = {'name': '田中', 'age': 25}
my_dict['email'] = 'tanaka@example.com'
print(my_dict)
# 出力: {'name': '田中', 'age': 25, 'email': 'tanaka@example.com'}
# 既存のキーに代入すると値が上書きされる
my_dict['age'] = 26
print(my_dict)
# 出力: {'name': '田中', 'age': 26, 'email': 'tanaka@example.com'}
変数をキーとして使う
user_data = {}
# 変数をキーとして使用
key = 'username'
value = 'tanaka123'
user_data[key] = value
# ループで複数追加
fields = [('name', '田中太郎'), ('age', 30), ('city', '東京')]
for k, v in fields:
user_data[k] = v
print(user_data)
# 出力: {'username': 'tanaka123', 'name': '田中太郎', 'age': 30, 'city': '東京'}
update()メソッドを使う方法
update()を使うと、複数のキーと値を一度に追加できます。
my_dict = {'item1': 1, 'item2': 2}
# 辞書を渡す
my_dict.update({'item3': 3, 'item4': 4})
print(my_dict)
# 出力: {'item1': 1, 'item2': 2, 'item3': 3, 'item4': 4}
# キーワード引数で渡す
my_dict.update(item5=5, item6=6)
print(my_dict)
# 出力: {'item1': 1, 'item2': 2, 'item3': 3, 'item4': 4, 'item5': 5, 'item6': 6}
# タプルのリストで渡す
my_dict.update([('item7', 7), ('item8', 8)])
print(my_dict)
update()で既存の値を更新
config = {'debug': False, 'timeout': 30, 'retries': 3}
# 既存のキーがあれば上書き、なければ追加
config.update({'debug': True, 'max_connections': 100})
print(config)
# 出力: {'debug': True, 'timeout': 30, 'retries': 3, 'max_connections': 100}
setdefault()メソッド
setdefault()は、キーが存在しない場合のみ値を追加します。
# キーが存在しない場合:追加される
user = {'name': '田中'}
user.setdefault('age', 25)
print(user) # {'name': '田中', 'age': 25}
# キーが存在する場合:何も変更されない
user.setdefault('name', '鈴木')
print(user) # {'name': '田中', 'age': 25}(名前は変わらない)
setdefault()の実用例
# カテゴリ別にグループ化
items = [
('果物', 'りんご'),
('野菜', 'にんじん'),
('果物', 'バナナ'),
('野菜', 'キャベツ'),
]
categories = {}
for category, item in items:
categories.setdefault(category, []).append(item)
print(categories)
# 出力: {'果物': ['りんご', 'バナナ'], '野菜': ['にんじん', 'キャベツ']}
Python 3.9+: マージ演算子 |
Python 3.9以降では、|演算子で辞書をマージできます。
# | 演算子(新しい辞書を作成)
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged = dict1 | dict2
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
print(dict1) # {'a': 1, 'b': 2}(元の辞書は変更されない)
# |= 演算子(元の辞書を更新)
dict1 |= dict2
print(dict1) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# キーが重複する場合は右側が優先
base = {'x': 1, 'y': 2}
override = {'y': 100, 'z': 3}
result = base | override
print(result) # {'x': 1, 'y': 100, 'z': 3}
Python 3.5+: アンパック演算子 **
Python 3.5以降では、**でアンパックして新しい辞書を作成できます。
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
# 新しい辞書を作成(元は変更されない)
merged = {**dict1, **dict2}
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# 追加の値も同時に設定可能
result = {**dict1, 'e': 5, 'f': 6}
print(result) # {'a': 1, 'b': 2, 'e': 5, 'f': 6}
実践例
設定のマージ
def load_config(user_config: dict = None) -> dict:
"""デフォルト設定とユーザー設定をマージ"""
default_config = {
'debug': False,
'timeout': 30,
'retries': 3,
'log_level': 'INFO'
}
if user_config is None:
return default_config
# Python 3.9+
return default_config | user_config
# Python 3.5-3.8
# return {**default_config, **user_config}
# 使用例
config = load_config({'debug': True, 'timeout': 60})
print(config)
# {'debug': True, 'timeout': 60, 'retries': 3, 'log_level': 'INFO'}
APIレスポンスの構築
def build_response(data: dict, status: str = 'success') -> dict:
"""APIレスポンスを構築"""
base = {
'status': status,
'timestamp': '2024-10-23T10:00:00Z'
}
base['data'] = data
return base
# 使用例
response = build_response({'user_id': 123, 'name': '田中'})
print(response)
# {'status': 'success', 'timestamp': '2024-10-23T10:00:00Z', 'data': {'user_id': 123, 'name': '田中'}}
辞書内包表記での追加
# 既存の辞書に変換を適用して新しい辞書を作成
prices = {'apple': 100, 'banana': 80, 'orange': 120}
# 税込み価格を追加
prices_with_tax = {
**prices,
**{f'{k}_with_tax': int(v * 1.1) for k, v in prices.items()}
}
print(prices_with_tax)
# {'apple': 100, 'banana': 80, 'orange': 120,
# 'apple_with_tax': 110, 'banana_with_tax': 88, 'orange_with_tax': 132}
パフォーマンスの比較
import timeit
# テスト用辞書
base = {f'key{i}': i for i in range(100)}
add = {f'new{i}': i for i in range(10)}
# 各方法の速度比較
def test_update():
d = base.copy()
d.update(add)
return d
def test_unpack():
return {**base, **add}
def test_merge_op(): # Python 3.9+
return base | add
# 結果: update()とマージ演算子が最も高速
# アンパックは新しいオブジェクトを作成するため若干遅い
よくあるエラーと対処
# TypeError: unhashable type(ハッシュ不可の型をキーに使用)
my_dict = {}
# my_dict[[1, 2]] = 'value' # エラー: リストはキーにできない
# タプルはキーにできる
my_dict[(1, 2)] = 'value'
print(my_dict) # {(1, 2): 'value'}
まとめ
| 状況 | 推奨方法 |
|---|---|
| 1項目追加 | dict[key] = value |
| 複数項目追加 | dict.update({...}) |
| 存在しない場合のみ追加 | dict.setdefault(key, value) |
| 辞書をマージ(新規作成) | dict1 | dict2(3.9+)または {**dict1, **dict2} |
| 辞書をマージ(更新) | dict1 |= dict2(3.9+)または dict1.update(dict2) |
目的に応じて適切な方法を選択することで、読みやすく効率的なコードを書くことができます。