3.4 默认字典
如果我们试图访问一个不在字典中的键,会得到一个错误。然而,如果一个字典能为这个新键自动创建一个条目并给它一个默认值,如 0 或者一个空链表,将是有用的。由于这个原因,可以使用一种特殊的称为defaultdict
的字典。为了使用它,我们必须提供一个参数,用来创建默认值,如int
, float
, str
, list
, dict
, tuple
。
>>> from collections import defaultdict
>>> frequency = defaultdict(int)
>>> frequency['colorless'] = 4
>>> frequency['ideas']
0
>>> pos = defaultdict(list)
>>> pos['sleep'] = ['NOUN', 'VERB']
>>> pos['ideas']
[]
注意
这些默认值实际上是将其他对象转换为指定类型的函数(例如int("2")
, list("2")
)。当它们不带参数被调用时——int()
, list()
——它们分别返回0
和[]
。
前面的例子中指定字典项的默认值为一个特定的数据类型的默认值。然而,也可以指定任何我们喜欢的默认值,只要提供可以无参数的被调用产生所需值的函数的名子。让我们回到我们的词性的例子,创建一个任一条目的默认值是'N'
的字典。当我们访问一个不存在的条目时,它会自动添加到字典。
>>> pos = defaultdict(lambda: 'NOUN') ![[1]](/projects/nlp-py-2e-zh/Images/7a979f968bd33428b02cde62eaf2b615.jpg)
>>> pos['colorless'] = 'ADJ'
>>> pos['blog'] ![[2]](/projects/nlp-py-2e-zh/Images/6ac827d2d00b6ebf8bbc704f430af896.jpg)
'NOUN'
>>> list(pos.items())
[('blog', 'NOUN'), ('colorless', 'ADJ')] # [_automatically-added]
注意
上面的例子使用一个 lambda 表达式,在4.4介绍过。这个 lambda 表达式没有指定参数,所以我们用不带参数的括号调用它。因此,下面的f
和g
的定义是等价的:
>>> f = lambda: 'NOUN'
>>> f()
'NOUN'
>>> def g():
... return 'NOUN'
>>> g()
'NOUN'
让我们来看看默认字典如何被应用在较大规模的语言处理任务中。许多语言处理任务——包括标注——费很大力气来正确处理文本中只出现过一次的词。如果有一个固定的词汇和没有新词会出现的保证,它们会有更好的表现。在一个默认字典的帮助下,我们可以预处理一个文本,替换低频词汇为一个特殊的“超出词汇表”词符UNK
。(你能不看下面的想出如何做吗?)
我们需要创建一个默认字典,映射每个词为它们的替换词。最频繁的 n 个词将被映射到它们自己。其他的被映射到UNK
。
>>> alice = nltk.corpus.gutenberg.words('carroll-alice.txt')
>>> vocab = nltk.FreqDist(alice)
>>> v1000 = [word for (word, _) in vocab.most_common(1000)]
>>> mapping = defaultdict(lambda: 'UNK')
>>> for v in v1000:
... mapping[v] = v
...
>>> alice2 = [mapping[v] for v in alice]
>>> alice2[:100]
['UNK', 'Alice', "'", 's', 'UNK', 'in', 'UNK', 'by', 'UNK', 'UNK', 'UNK',
'UNK', 'CHAPTER', 'I', '.', 'UNK', 'the', 'Rabbit', '-', 'UNK', 'Alice',
'was', 'beginning', 'to', 'get', 'very', 'tired', 'of', 'sitting', 'by',
'her', 'sister', 'on', 'the', 'UNK', ',', 'and', 'of', 'having', 'nothing',
'to', 'do', ':', 'once', 'or', 'twice', 'she', 'had', 'UNK', 'into', 'the',
'book', 'her', 'sister', 'was', 'UNK', ',', 'but', 'it', 'had', 'no',
'pictures', 'or', 'UNK', 'in', 'it', ',', "'", 'and', 'what', 'is', 'the',
'use', 'of', 'a', 'book', ",'", 'thought', 'Alice', "'", 'without',
'pictures', 'or', 'conversation', "?'" ...]
>>> len(set(alice2))
1001