setdefault() 是什么?
setdefault() 是 Python 字典的一个内置方法,它的主要作用是:如果字典中存在给定的键,则返回该键对应的值;如果键不存在,则在字典中插入这个键,并将其值设置为一个指定的默认值,然后返回这个默认值。

它是一个结合了 get() 和 __setitem__(通过 key = value 语法赋值)功能的便捷方法。
语法
dictionary.setdefault(key, default_value)
key: 要在字典中查找的键。default_value(可选): 如果键key不存在时,要设置的默认值。- 如果省略
default_value参数,则默认为None。
- 如果省略
工作原理与返回值
setdefault() 方法总是返回指定键 key 对应的值。
-
键已存在
- 它不会修改字典中该键的值。
- 它直接返回该键现有的值。
-
键不存在
(图片来源网络,侵删)- 它会在字典中添加一个新的键值对
key: default_value。 - 它返回这个新设置的
default_value。
- 它会在字典中添加一个新的键值对
示例演示
让我们通过几个例子来清晰地理解它的行为。
示例 1:键已存在
my_dict = {'name': 'Alice', 'age': 30}
# 'name' 键已存在
value = my_dict.setdefault('name', 'Unknown')
print(f"返回的值: {value}")
print(f"修改后的字典: {my_dict}")
输出:
返回的值: Alice
修改后的字典: {'name': 'Alice', 'age': 30}
分析:
- 因为
'name'已经存在于my_dict中,setdefault()直接返回其值'Alice',没有改变**。
示例 2:键不存在(提供了默认值)
my_dict = {'name': 'Alice', 'age': 30}
# 'city' 键不存在
value = my_dict.setdefault('city', 'New York')
print(f"返回的值: {value}")
print(f"修改后的字典: {my_dict}")
输出:

返回的值: New York
修改后的字典: {'name': 'Alice', 'age': 30, 'city': 'New York'}
分析:
- 因为
'city'不存在于my_dict中,setdefault()先向字典中添加了'city': 'New York'这个键值对。 - 然后返回这个新设置的默认值
'New York'。
示例 3:键不存在(未提供默认值)
my_dict = {'name': 'Alice', 'age': 30}
# 'country' 键不存在,且未提供默认值
value = my_dict.setdefault('country')
print(f"返回的值: {value}")
print(f"修改后的字典: {my_dict}")
输出:
返回的值: None
修改后的字典: {'name': 'Alice', 'age': 30, 'country': None}
分析:
- 当未提供
default_value时,默认为None。 'country'键不存在,setdefault()向字典中添加了'country': None。- 然后返回
None。
与 get() 的关键区别
这是初学者最容易混淆的地方。setdefault() 和 get() 在“键不存在”时的行为是相似的,但关键区别在于“键不存在时是否会修改字典”。
| 特性 | dict.get(key, default) |
dict.setdefault(key, default) |
|---|---|---|
| 键不存在时 | 返回 default |
添加 key: default 到字典,然后返回 default |
| 键已存在时 | 返回键的现有值 | 返回键的现有值,不修改字典 |
| 是否修改字典 | 从不修改 | 可能修改(仅在键不存在时) |
对比示例:
# 使用 get()
d1 = {'a': 1}
val_get = d1.get('b', 0)
print(f"get() 返回的值: {val_get}")
print(f"使用 get() 后的字典: {d1}")
# 输出:
# get() 返回的值: 0
# 使用 get() 后的字典: {'a': 1} (字典未改变)
print("-" * 20)
# 使用 setdefault()
d2 = {'a': 1}
val_setdefault = d2.setdefault('b', 0)
print(f"setdefault() 返回的值: {val_setdefault}")
print(f"使用 setdefault() 后的字典: {d2}")
# 输出:
# setdefault() 返回的值: 0
# 使用 setdefault() 后的字典: {'a': 1, 'b': 0} (字典已改变)
实际应用场景
setdefault() 最经典的用途是构建分组字典(grouping items)。
假设你有一个水果列表,你想按颜色对它们进行分组。
场景: 将水果按颜色分类。
fruits = [
{'name': 'apple', 'color': 'red'},
{'name': 'banana', 'color': 'yellow'},
{'name': 'cherry', 'color': 'red'},
{'name': 'lemon', 'color': 'yellow'},
]
# 目标:创建一个如下的字典
# {
# 'red': ['apple', 'cherry'],
# 'yellow': ['banana', 'lemon']
# }
# --- 方法一:使用 if/else (繁琐) ---
grouped_1 = {}
for fruit in fruits:
color = fruit['color']
name = fruit['name']
if color in grouped_1:
grouped_1[color].append(name)
else:
grouped_1[color] = [name]
print("--- 方法一 (if/else) ---")
print(grouped_1)
# 输出: {'red': ['apple', 'cherry'], 'yellow': ['banana', 'lemon']}
# --- 方法二:使用 setdefault() (优雅简洁) ---
grouped_2 = {}
for fruit in fruits:
color = fruit['color']
name = fruit['name']
# color 不在 grouped_2 中,setdefault 会先设置 grouped_2[color] = []
# 然后返回这个空列表,.append(name) 就可以执行了
grouped_2.setdefault(color, []).append(name)
print("\n--- 方法二 (setdefault) ---")
print(grouped_2)
# 输出: {'red': ['apple', 'cherry'], 'yellow': ['banana', 'lemon']}
分析:
在方法二中,grouped_2.setdefault(color, []).append(name) 这一行代码非常精炼:
- 检查
color是否是grouped_2的一个键。 - 如果是,返回
grouped_2[color]对应的列表(如['apple'])。 - 如果不是,在
grouped_2中创建一个新键color,并将其值设置为[](一个空列表),然后返回这个空列表。 - 无论哪种情况,
append(name)都会执行,将水果名添加到正确的颜色列表中。
这避免了每次都要检查键是否存在,代码更清晰、更 Pythonic。
| 方法 | 核心功能 | 优点 | 缺点/注意事项 |
|---|---|---|---|
setdefault() |
获取值,如果键不存在则添加键和默认值 | 代码简洁,特别适合构建分组字典 | 如果键不存在,会修改原字典,这可能不是你想要的(此时用 get() 更安全) |
get() |
获取值,如果键不存在则返回默认值,不修改字典 | 安全,只读操作,不会改变字典内容 | 无法直接用于需要初始化新键的场景,需要额外代码(如 if key not in dict: dict[key] = value) |
何时使用 setdefault()?
当你希望如果某个键不存在,就立刻创建它并赋予一个初始值,然后对这个值进行操作时,setdefault() 是绝佳选择,最常见的场景就是上述的“分组”操作。
何时使用 get()?
当你只需要安全地获取一个键的值,并为其提供一个备选方案,但
