使用defaultdict精简Python代码
普通dict实现计数统计
我们常常用Python的dict
来做简单的计数统计。先看下面一段代码:
1 | names = ['alice','bob','cindy','ocre','alice','ocre','ocre','cindy','tom'] |
这段代码能够统计出每个名字出现的次数。这里我们使用了普通的dict
结构names_counts来保存名字和出现次数的映射关系。我们知道,如果直接访问字典中不存在的键,会抛出KeyError
异常。比如:
1 | name_counts = {} |
为了避免KeyError
异常,通常需要使用一个if name in name_counts: ... else ...
的代码段来检查词典中是否存在特定的键。如果键已经存在,则直接累加操作,如果不存在,则先赋一个初始值。
引入defaultdict来简化代码
对于有代码洁癖的猿来说,这样的代码仍然有一股坏味道。我们可以用defaultdict
来简化一下。简化后的代码如下:
1 | from collections import defaultdict |
可见,在引入defaultdict
后,烦人的if-else
被干掉了。(BTW, 统计代码还可以利用其他方法进一步简化,参考我的另一篇博文:Python中实现计数统计的4种方法)
引申:如何构造defaultdict?
这里我们使用了defaultdict
来代替普通dict
,来给name_counts中不存在的键设置默认值,默认值由defaultdict()
的第一个参数确定。
构造defaultdict
,需传递一个工厂函数作为参数:
1 | mydict = collections.defaultdict( factory_function ) |
这里的工厂函数,可以是普通类型,比如 list
,set
,str
,int
等,当访问一个不存在键不存在时,返回这些类型的默认值,比如:
1 | from collections import defaultdict |
工厂函数也可以是普通的无参函数,比如:
1 | >>> from collections import defaultdict |
工厂函数还可以用lambda表达式(匿名函数)来代替,比如:
1 | from collections import defaultdict |