前面讨论了如果一个字典中有“键”找不到,共有四种解决方式。 这四种办法中,get 方案要胜过利用 in 表达式和 KeyError 异常来解决的那两种方案,对于某些用例,我们可能觉得 setdefault 应该是代码最简短的办法。
总结
- 如果你管理的字典可能需要添加任意的键,那么应该考虑能否用内置的 collections 模块中的 defaultdict 实例来解决问题。
- 如果这种键名比较随意的字典是别人传给你的,你无法把它创建成 defaultdict, 那么应该考虑通过 get 方法访问其中的键值。在个别情况下,也可以考虑改用 setdefault 方法,因为那样写更短。
对于 get 方式 - 比较 setdefault
例如,笔者要记录自己去过哪些国家,还要记录在每个国家到过哪些城市。那可以用这样一个字典,把国名与包含城市名称的集(set)关联起来。
visits = {
'Mexico': {'Tulum', 'Puerto Vallarta'},
'Japan': {'Hakone'},
}
- 通过 setdefault 方案把新的城市添加到对应的集里,
- 这要比利用 get 方法与赋值表达式(Python 3.8 的新特性)来实现的方案短很多。 ```python visits.setdefault(‘France’, set()).add(‘Arles’) # Short
if (japan := visits.get(‘Japan’)) is None: # Long,这里有赋值表达式 visits[‘Japan’] = japan = set()
japan.add(‘Kyoto’)
print(visits)

<a name="Tzhgd"></a>
# 封装类 - setdefault 方法
- 对于上面的问题,写一个类
```python
class Visits:
def __init__(self):
self.data = {}
def add(self, country, city):
city_set = self.data.setdefault(country, set())
city_set.add(city)
# 调用
visits = Visits()
visits.add('Russia', 'Yekaterinburg')
visits.add('Tanzania', 'Zanzibar')
print(visits.data)
- 用 setdefault 不够高效,因为无论 country 在不在 字典里,都会创建一个新的 set 实例
-
封装类 - defaultset 方法
在键缺失的情况下,自动添加这个键以及键所对应的默认值 ```python from collections import defaultdict
class Visits: def init(self): self.data = defaultdict(set) def add(self, country, city): self.data[country].add(city)
visits = Visits()
visits.add(‘England’, ‘Bath’)
visits.add(‘England’, ‘London’)
print(visits.data)
```
- 这种任务用 defaultdict 实现要比用 setdefault 好得多
- 节省开销