初次见到defaultdict是在一篇《一行Python代码定义树》的文章中。
文章中定义的结构:
def tree():
return defaultdict(tree)
这里应用了递归定义。help(defaultdict)可以发看到他是一个类,并且提供的方法类似dict类,通过文档了解到他是一个带工场方法或工厂类的字典。当所访问的键不存在时,会调用工厂方法或工厂类生成默认值。
这个定义生成的是一个defaultdict嵌套结构,可以看做一个dict嵌套结构,因为defaultdict可以看成带默认值的dict。这个结构的好处是,永远不会出现键不存在的错误(KeyError),因为键不存在的时候会调用工场函数tree,生成对应的值,这里生成的值仍是一个defaultdict对象,所以无论深度多大,都不会出现KeyError。
文章中的测试数据:
users = tree()
users['harold']['username'] =
'hrldcpr'
users['handler']['username'] =
'matthandlersux'
users对应的dict为:
{"harold": {"username": "hrldcpr"}, "handler": {"username": "matthandlersux"}}
通过观察发现defaultdict类提供了__iter__方法,所以defaultdict类对象是一个可迭代对象,迭代方式和dict类似,对键进行迭代。
这个类在创建某些需要默认值的字典时实用,比如官方文档上给出的例子:
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list) >>> for k, v in s: ... d[k].append(v) ...
>>> d.items() [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
如果改用dict的,每次执行d[k].append(v)时要用has_key()方法判断键是否存在,不存在时设置对应的值为[]。