推荐阅读:
数据科学的秘密武器:defaultdict——Python字典的自动化填充神器,让数据结构更灵活
一、什么是setdefault
Python中的
setdefault
方法是字典(dict
)类型的一个非常实用的方法,它允许开发者在尝试访问字典中不存在的键时,自动为该键设置一个默认值,并返回这个默认值。
二、setdefault
基本功能
setdefault
方法的基本功能是:在字典中查找指定的键,如果该键存在,则返回其对应的值;如果该键不存在,则在字典中插入该键,并将其值设置为指定的默认值,然后返回这个默认值。
语法
dict.setdefault(key, default=None)
key
:要查找或添加的键。default
:可选参数,当键不存在于字典中时返回的默认值。如果未提供,则默认为None
。
返回值
- 如果
key
在字典中,则返回key
对应的值。 - 如果
key
不在字典中,则插入key
并将其值设为default
,然后返回default
。
工作原理
- 查找键:首先,
setdefault
方法会在字典中查找指定的key
。 - 存在性检查:
- 如果
key
存在,则直接返回该key
对应的值。 - 如果
key
不存在,则执行下一步。
- 如果
- 添加新键值对:在字典中插入一个新的键值对,其中
key
是传入的键,value
是传入的default
值(如果未提供,则为None
)。 - 返回默认值:最后,返回新插入的或已存在的
key
对应的值(在key
不存在的情况下,即为default
值)。
优势
- 简化代码:
setdefault
方法避免了在访问字典键之前进行显式的存在性检查,从而简化了代码。 - 提高可读性:使用
setdefault
可以使代码更加简洁和易于理解,因为它将查找和添加操作合并为一个步骤。 - 避免
KeyError
:在尝试访问不存在的键时,setdefault
方法不会引发KeyError
异常,而是优雅地处理这种情况。
使用场景
- 统计或累加字典中某些键的值:当需要统计列表中元素出现的次数时,
setdefault
方法非常有用。 - 初始化字典中的键:在构建字典时,如果希望某些键具有默认值,可以使用
setdefault
来初始化这些键。 - 处理嵌套字典:在处理嵌套字典时,
setdefault
可以方便地初始化不存在的嵌套层。
三、setdefault和defaultdict的区别
Python中的
setdefault
和defaultdict
都是在处理字典时非常有用的工具,它们都能在一定程度上避免KeyError
异常,但它们在实现方式和应用场景上存在一些区别。
setdefault
setdefault
是字典(dict
)的一个实例方法,它接受两个参数:要查找的键(key
)和默认值(default
,默认为None
)。如果字典中存在该键,则返回该键对应的值;如果不存在,则将该键添加到字典中,并将其值设为默认值,然后返回这个默认值。
特点
- 是字典的一个方法,不需要导入额外的模块。
- 只在需要时才设置默认值,避免了不必要的内存占用。
- 返回值是键对应的值,如果键是新添加的,则返回默认值。
使用场景
- 当你需要统计或累加字典中某些键的值时,
setdefault
非常有用。 - 当你不确定字典中是否存在某个键,但想要安全地访问或修改其值时。
defaultdict
defaultdict
是collections
模块中的一个工厂函数,用于构建具有默认值的字典。它接受一个工厂函数作为参数,如list
、set
、str
、int
等。当访问字典中不存在的键时,defaultdict
会自动为该键创建一个条目,并将工厂函数的返回值作为该键的值。
特点
- 需要从
collections
模块导入。 - 为所有不存在的键提供统一的默认值类型,避免了在访问时单独设置默认值的麻烦。
- 适用于需要默认值是列表、集合等复杂类型的情况。
使用场景
- 当你需要构建一个字典,其所有键都应该有相同的默认值类型(如列表、集合)时。
- 当你想要简化代码,避免在访问不存在的键时编写冗长的条件语句时。
区别总结
setdefault | defaultdict | |
来源 | 字典的实例方法 | collections模块的工厂函数 |
参数 | key , default=None | 工厂函数(如list , set , str , int 等) |
返回值 | 键对应的值(如果键是新添加的,则返回默认值) | 键对应的值(如果键不存在,则自动创建并返回工厂函数的返回值) |
使用场景 | 统计或累加字典中某些键的值,安全地访问或修改字典中的值 | 需要所有键具有相同默认值类型的字典,简化代码以避免冗长的条件语句 |
内存占用 | 只在需要时设置默认值,较为节省内存 | 所有不存在的键都会自动设置默认值,可能增加内存占用 |
四、代码案例
案例 1: 统计列表中元素的出现次数
# 定义一个列表,包含一些重复的元素
elements = ['apple', 'banana', 'apple', 'orange', 'banana', 'grape', 'apple']
# 初始化一个空字典来存储元素及其出现次数
count = {}
# 遍历列表中的每个元素
for element in elements:
# 使用setdefault方法统计元素的出现次数
# 如果元素在字典中不存在,则添加该元素并将值设为0,然后返回0;
# 如果元素已存在,则直接返回该元素当前的值
count[element] = count.setdefault(element, 0) + 1
# 打印统计结果
print(count) # 预期输出: {'apple': 3, 'banana': 2, 'orange': 1, 'grape': 1}
案例 2: 初始化嵌套字典
# 初始化一个空字典
nested_dict = {}
# 使用setdefault方法初始化嵌套字典的多个层级
# 如果'level1'不存在,则添加'level1'并将值设为空字典,然后返回这个空字典
# 接着,在返回的空字典上再次使用setdefault来添加'level2',依此类推
nested_dict.setdefault('level1', {}).setdefault('level2', {}).setdefault('level3', 0)
# 打印结果
print(nested_dict) # 预期输出: {'level1': {'level2': {'level3': 0}}}
# 现在我们可以直接访问或修改嵌套字典的深层级
nested_dict['level1']['level2']['level3'] = 5
print(nested_dict) # 预期输出: {'level1': {'level2': {'level3': 5}}}
案例 3: 使用setdefault进行默认值设置
# 初始化一个空字典
my_dict = {}
# 尝试获取键'a'的值,如果不存在则设为默认值'default_value'
value_a = my_dict.setdefault('a', 'default_value')
print(value_a) # 预期输出: default_value
print(my_dict) # 预期输出: {'a': 'default_value'}
# 再次尝试获取键'a'的值,此时'a'已存在
value_a_again = my_dict.setdefault('a', 'new_value')
print(value_a_again) # 预期输出: default_value,因为'a'已存在,不会改变其值
print(my_dict) # 预期输出: {'a': 'default_value'}
# 尝试获取键'b'的值,如果不存在则设为默认值'another_default'
value_b = my_dict.setdefault('b', 'another_default')
print(value_b) # 预期输出: another_default
print(my_dict) # 预期输出: {'a': 'default_value', 'b': 'another_default'}