一. 映射的弹性键查询
某个键在映射里不存在,我们也希望在通过这个键读取值的时候能得到一个默认值。有两个途径能帮我们达到这个目的,一个是通过 defaultdict 这个类型而不是普通的 dict,另一个是给自己定义一个 dict 的子类,然后在子类中实现 __missing__ 方法。
1.1 defaultdict:处理找不到的键的一个选择
在实例化一个 defaultdict 的时候,需要给构造方法提供一个可调用对象,这个可调用对象会在 __getitem__ 碰到找不到的键 的时候被调用,让 __getitem__ 返回某种默认值。
演示1 个用来生成默认值的可调用对象存放在名为 default_factory 的实例属性里
演示2 利用 defaultdict 实例而不是setdefault 方法(还是上一节的示例,改用defaultdict代替setdefault方法)
"""创建一个从单词到其出现情况的映射"""
import sys
import re
import collections
WORD_RE = re.compile(r'\w+')
index = collections.defaultdict(list)
with open(sys.argv[1], encoding='utf-8') as f:
for line_no, line in enumerate(f, 1):
for match in WORD_RE.finditer(line):
word = match.group()
column_no = match.start()+1
location = (line_no, column_no)
index[word].append(location)
for word in sorted(index, key=str.upper):
print(word, index[word])
如果 index 并没有 word 的记录,那么 default_factory 会被调 用,为查询不到的键创造一个值。这个值在这里是一个空的列表,然后这个空列表被赋值给 index[word],继而被当作返回值返回,因此 .append(location) 操作总能成功。
注意:
-
如果在创建 defaultdict 的时候没有指定 default_factory ,查询不存在的键会触发 KeyError 。
-
defaultdict 里的 default_factory 只会在 __getitem__ 里被调用,在其他的方法里完全不会发挥作用。
-
比 如, dd 是个