3.4 默认字典

如果我们试图访问一个不在字典中的键,会得到一个错误。然而,如果一个字典能为这个新键自动创建一个条目并给它一个默认值,如 0 或者一个空链表,将是有用的。由于这个原因,可以使用一种特殊的称为defaultdict的字典。为了使用它,我们必须提供一个参数,用来创建默认值,如int, float, str, list, dict, tuple

  1. >>> from collections import defaultdict
  2. >>> frequency = defaultdict(int)
  3. >>> frequency['colorless'] = 4
  4. >>> frequency['ideas']
  5. 0
  6. >>> pos = defaultdict(list)
  7. >>> pos['sleep'] = ['NOUN', 'VERB']
  8. >>> pos['ideas']
  9. []

注意

这些默认值实际上是将其他对象转换为指定类型的函数(例如int("2"), list("2"))。当它们不带参数被调用时——int(), list()——它们分别返回0[]

前面的例子中指定字典项的默认值为一个特定的数据类型的默认值。然而,也可以指定任何我们喜欢的默认值,只要提供可以无参数的被调用产生所需值的函数的名子。让我们回到我们的词性的例子,创建一个任一条目的默认值是'N'的字典[1]。当我们访问一个不存在的条目时[2],它会自动添加到字典[3]

  1. >>> pos = defaultdict(lambda: 'NOUN') ![[1]](/projects/nlp-py-2e-zh/Images/7a979f968bd33428b02cde62eaf2b615.jpg)
  2. >>> pos['colorless'] = 'ADJ'
  3. >>> pos['blog'] ![[2]](/projects/nlp-py-2e-zh/Images/6ac827d2d00b6ebf8bbc704f430af896.jpg)
  4. 'NOUN'
  5. >>> list(pos.items())
  6. [('blog', 'NOUN'), ('colorless', 'ADJ')] # [_automatically-added]

注意

上面的例子使用一个 lambda 表达式,在4.4介绍过。这个 lambda 表达式没有指定参数,所以我们用不带参数的括号调用它。因此,下面的fg的定义是等价的:

  1. >>> f = lambda: 'NOUN'
  2. >>> f()
  3. 'NOUN'
  4. >>> def g():
  5. ... return 'NOUN'
  6. >>> g()
  7. 'NOUN'

让我们来看看默认字典如何被应用在较大规模的语言处理任务中。许多语言处理任务——包括标注——费很大力气来正确处理文本中只出现过一次的词。如果有一个固定的词汇和没有新词会出现的保证,它们会有更好的表现。在一个默认字典的帮助下,我们可以预处理一个文本,替换低频词汇为一个特殊的“超出词汇表”词符UNK。(你能不看下面的想出如何做吗?)

我们需要创建一个默认字典,映射每个词为它们的替换词。最频繁的 n 个词将被映射到它们自己。其他的被映射到UNK

  1. >>> alice = nltk.corpus.gutenberg.words('carroll-alice.txt')
  2. >>> vocab = nltk.FreqDist(alice)
  3. >>> v1000 = [word for (word, _) in vocab.most_common(1000)]
  4. >>> mapping = defaultdict(lambda: 'UNK')
  5. >>> for v in v1000:
  6. ... mapping[v] = v
  7. ...
  8. >>> alice2 = [mapping[v] for v in alice]
  9. >>> alice2[:100]
  10. ['UNK', 'Alice', "'", 's', 'UNK', 'in', 'UNK', 'by', 'UNK', 'UNK', 'UNK',
  11. 'UNK', 'CHAPTER', 'I', '.', 'UNK', 'the', 'Rabbit', '-', 'UNK', 'Alice',
  12. 'was', 'beginning', 'to', 'get', 'very', 'tired', 'of', 'sitting', 'by',
  13. 'her', 'sister', 'on', 'the', 'UNK', ',', 'and', 'of', 'having', 'nothing',
  14. 'to', 'do', ':', 'once', 'or', 'twice', 'she', 'had', 'UNK', 'into', 'the',
  15. 'book', 'her', 'sister', 'was', 'UNK', ',', 'but', 'it', 'had', 'no',
  16. 'pictures', 'or', 'UNK', 'in', 'it', ',', "'", 'and', 'what', 'is', 'the',
  17. 'use', 'of', 'a', 'book', ",'", 'thought', 'Alice', "'", 'without',
  18. 'pictures', 'or', 'conversation', "?'" ...]
  19. >>> len(set(alice2))
  20. 1001