dict的setfault方法我们可能使用的比较少,但是一旦使用则可以减少键的查询次数,从而让程序更高效.
源码注释:D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
说明:当D中不存在k时,相当于D.get(k,d) 和 D[k]=d;否则相当于D.get(k,d).
使用setfault处理找不到的键
当使用d[k]
查找不正确的键k
时,则会抛出异常KeyError
;我们可以使用d.get(k, default)
来代替d[k]
(当找不到键k时返回一个默认的值);但是当我们要更新键对应的值时候,使用__getitem__
或get
都效率比较低,此时使用setfault
则更高效.
例如下面的例子:从文本文件中读取数据并记录单词的行号和在每行中的索引位置.
文本文件
python11111book
java22222java
javascript33333javascript
python程序
import re
import sys
WORD_RE = re.compile(r'[a-zA-Z]+')
index = {}
with open('word.txt', 'rb') 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.setdefault(word, []).append(location)
print(index)
输出
{'python': [(1, 1)], 'book': [(1, 12)], 'java': [(2, 1), (2, 10)], 'javascript': [(3, 1), (3, 16)]}
分析
index.setdefault(word, []).append(location)
和
if key not in index:
index[word] = []
index[word].append(location)
二者是等价的,但是前者的效率比后者高,原因:后者如果键word
存在时需要进行两次查询,否则需要进行三次查询,最后才能更新;而使用setfault
只需要进行一次查询.