- 3.5 递增地更新字典
3.5 递增地更新字典
我们可以使用字典计数出现的次数,模拟fig-tally所示的计数词汇的方法。首先初始化一个空的defaultdict,然后处理文本中每个词性标记。如果标记以前没有见过,就默认计数为零。每次我们遇到一个标记,就使用+=运算符递增它的计数。
>>> from collections import defaultdict>>> counts = defaultdict(int)>>> from nltk.corpus import brown>>> for (word, tag) in brown.tagged_words(categories='news', tagset='universal'):... counts[tag] += 1...>>> counts['NOUN']30640>>> sorted(counts)['ADJ', 'PRT', 'ADV', 'X', 'CONJ', 'PRON', 'VERB', '.', 'NUM', 'NOUN', 'ADP', 'DET']>>> from operator import itemgetter>>> sorted(counts.items(), key=itemgetter(1), reverse=True)[('NOUN', 30640), ('VERB', 14399), ('ADP', 12355), ('.', 11928), ...]>>> [t for t, c in sorted(counts.items(), key=itemgetter(1), reverse=True)]['NOUN', 'VERB', 'ADP', '.', 'DET', 'ADJ', 'ADV', 'CONJ', 'PRON', 'PRT', 'NUM', 'X']
3.3中的列表演示了一个重要的按值排序一个字典的习惯用法,来按频率递减顺序显示词汇。sorted()的第一个参数是要排序的项目,它是由一个词性标记和一个频率组成的元组的列表。第二个参数使用函数itemgetter()指定排序的键。在一般情况下,itemgetter(n)返回一个函数,这个函数可以在一些其他序列对象上被调用获得这个序列的第 n 个元素,例如:
>>> pair = ('NP', 8336)>>> pair[1]8336>>> itemgetter(1)(pair)8336
sorted()的最后一个参数指定项目是否应被按相反的顺序返回,即频率值递减。
在3.3的开头还有第二个有用的习惯用法,那里我们初始化一个defaultdict,然后使用for循环来更新其值。下面是一个示意版本:
>>> my_dictionary = defaultdict(function to create default value)``>>> for item in sequence:``... my_dictionary[item_key] is updated with information about item
下面是这种模式的另一个示例,我们按它们最后两个字母索引词汇:
>>> last_letters = defaultdict(list)>>> words = nltk.corpus.words.words('en')>>> for word in words:... key = word[-2:]... last_letters[key].append(word)...>>> last_letters['ly']['abactinally', 'abandonedly', 'abasedly', 'abashedly', 'abashlessly', 'abbreviately','abdominally', 'abhorrently', 'abidingly', 'abiogenetically', 'abiologically', ...]>>> last_letters['zy']['blazy', 'bleezy', 'blowzy', 'boozy', 'breezy', 'bronzy', 'buzzy', 'Chazy', ...]
下面的例子使用相同的模式创建一个颠倒顺序的词字典。(你可能会试验第 3 行来弄清楚为什么这个程序能运行。)
>>> anagrams = defaultdict(list)>>> for word in words:... key = ''.join(sorted(word))... anagrams[key].append(word)...>>> anagrams['aeilnrt']['entrail', 'latrine', 'ratline', 'reliant', 'retinal', 'trenail']
由于积累这样的词是如此常用的任务,NLTK 提供一个创建defaultdict(list)更方便的方式,形式为nltk.Index()。
>>> anagrams = nltk.Index((''.join(sorted(w)), w) for w in words)>>> anagrams['aeilnrt']['entrail', 'latrine', 'ratline', 'reliant', 'retinal', 'trenail']
注意
nltk.Index是一个支持额外初始化的defaultdict(list)。类似地,nltk.FreqDist本质上是一个额外支持初始化的defaultdict(int)(附带排序和绘图方法)。
