当以 dict[key]
的形式获取字典中某个键的值的时候,如果 key
不在字典中,我们将得到一个 KeyError
异常。由于处理异常需要写额外的代码,所以我们往往更多的使用 dict.get(key, defalut)
的形式来获取字典中某个键的值。这种情况下如果 key
不在这个 dict
中,也会返回一个指定的默认值 default
,而不至于抛出异常。
使用 setdefault
在实际工作中,我们从数据库中查询的数据有可能是下面这种形式。
1 | data = [('one', 1), ('one', 2), ('two', 1), ('two', 2,), ('three', 1)] |
现在需要将其转换为字典,并根据列表中每个元组的第一个元素当作键来进行分组,将所有键相同的值存放到列表中,结果如下。
1 | d = { |
将列表转换为字典的过程,我们有可能写出这样的代码:
1 | d = {} |
这段代码逻辑比较简单,在 for
循环中,每次获取到对应的 key
的值,如果不存在就初始化一个空列表,然后将新的值追加到列表中,最后重新赋值给字典对应的 key
。
这样虽然能够实现功能,但在 Python 中实现它我们还有更好的办法,即使用字典的 setdefault
方法为不存在的 key
赋予默认值。
1 | d = {} |
如你所见,之前用三行代码才能解决的问题,使用 setdefault
后只需要一行代码即可搞定。
事实上,使用 setdefault
不止在于代码更加的简洁,它还能提高程序执行效率。当调用 d.setdefault(key, [])
时,如果在 d
中查询不到 key
,setdefault
会直接创建一个空列表并赋值给 d[key]
,最后返回这个新创建的空列表,所以能够在后续直接调用列表的 append
方法对其进行更新操作。这个过程只会在 d
中查询一次 key
这个键,而之前的做法中则需要查询两次。
使用 defaultdict
defaultdict
是 Python 标准库 collections
下提供的一个能够以 Pythonic
的方式解决上面问题的另一种实现方案。
defaultdict
跟普通的 dict
用法几乎一样,只不过需要在其构造方法中提供一个可调用对象作为参数。当在字典中查询某个 key
不存在时,这个可调用对象的返回结果即为这个 key
的默认值。
以下是使用 defaultdict
来解决上面问题的代码示例:
1 | from collections import defaultdict |
注意:在实例化 defaultdict
时,如果没有传入参数,字典仍能够被正常创建,但当遇到不存在的 key
时就会抛出 KeyError
异常。