在旧文 Python应用之文本分析 中,其中用到了一个功能是词频统计。当时小编采用的思路是这样的:
需要两个list,一个存储单词,一个存储对应的词频。当遇到一个单词,判断是否在这个list中,如果是,则词频加1;如果否,则单词list新增这个单词,同时对应的词频设置为1。
对应的代码如下:
# 搜寻单词 word 是否在 wordList中
# 若在其中,返回其index; 若不在,返回-1
def getIndex(wordList, word):
index = 0
while index < len(wordList):
if wordList[index] == word:
return index
index = index + 1
return -1
# 统计单词出现的频次
def computeFrequencies(wordList):
# 维护单词列表
masterList = []
# 维护单词对应的频次
frequencies = []
for word in wordList:
# 查找单词是否在单词列表中
loc = getIndex(masterList, word)
if loc >= 0:
# 在单词列表中频次加1
frequencies[loc] = frequencies[loc] + 1
else:
# 没在单词列表中,则添加该单词,并将频次设置为1
masterList.append(word)
frequencies.append(1)
return [masterList, frequencies]
思路很清晰,但是,有没有更为高效的实现方式呢?
在查找一个元素的时候,最高效的查找方式是什么?很明显,是通过哈希值来进行查找的,算法复杂度是 O(1)。在Java中是 HashMap,在Python中呢?对,是字典。于是,上述代码可以用字典来高效实现,并且代码也会更加简洁:
# 统计单词出现的频次
def computeFrequencies(wordList):
#词频字典
wordfrequencies = {}
for word in wordList:
if word not in wordfrequencies:
# 单词不在单词词频字典中, 词频设置为1
wordfrequencies[word] = 1
else:
# 单词在单词词频字典中, 词频加1
wordfrequencies[word] = wordfrequencies[word] + 1
# 字典转换为列表
masterList = list(wordfrequencies.keys())
frequencies = list(wordfrequencies.values())
return [masterList, frequencies]
在字典中,我们需要每次判断 word 是不是在字典中,否则会报KeyError。这样是否会有些繁琐?有没有什么办法避免此问题?答案是肯定的,可以通过dict.setdefault() 来设置默认值,即 Key 不在字典中时的初始值。这样,代码更为简洁了:
# 统计单词出现的频次
def computeFrequencies(wordList):
#词频字典
wordfrequencies = {}
for word in wordList:
# 设置默认值
wordfrequencies.setdefault(word, 0)
# 单词词频加1
wordfrequencies[word] = wordfrequencies[word] + 1
# 字典转换为列表
masterList = list(wordfrequencies.keys())
frequencies = list(wordfrequencies.values())
return [masterList, frequencies]
那么,Python中有没有现成的设置默认值的字典? Python功能这么强大,答案是肯定的。Python中的 collections 中的 defaultdict 就实现了这项功能:
from collections import defaultdict
# 统计单词出现的频次
def computeFrequencies(wordList):
#词频字典
wordfrequencies = defaultdict(lambda: 0)
for word in wordList:
# 单词词频加1
wordfrequencies[word] = wordfrequencies[word] + 1
# 字典转换为列表
masterList = list(wordfrequencies.keys())
frequencies = list(wordfrequencies.values())
return [masterList, frequencies]
代码更简洁了。那么,Python中有没有统计词频这样的计数功能呢?强大的Python怎么会说不呢。 collection 中的 Counter 类就完成了这样的功能,它是字典类的一个子类。代码似乎简洁的令你不敢想象:
# 统计单词出现的频次
def computeFrequencies(wordList):
#词频字典
wordfrequencies = Counter(wordList)
# 字典转换为列表
masterList = list(wordfrequencies.keys())
frequencies = list(wordfrequencies.values())
return [masterList, frequencies]
今天,你深入理解了Python中如何进行词频统计或者计数了吗? Python功能的强大是否让你更爱上了Python?