如何使用python更快地计算大单词列表中单词的计数频率并成为字典

时间:2016-10-17 08:54:03

标签: python performance list python-3.x dictionary

有一个很长的单词列表,列表的长度大约是360000.我想得到每个单词的频率,并且是一个字典。

例如:

{'I': 50, 'good': 30,.......}

由于单词列表很大,我发现计算它需要花费很多时间。你有更快的方法来实现这个目标吗?

到目前为止,我的代码如下:

  dict_pronoun = dict([(i, lst_all_tweet_noun.count(i)) for i in 
                        lst_all_tweet_noun])
  sorted(dict_pronoun)

1 个答案:

答案 0 :(得分:9)

你在做错了几件事:

  • 您首先构建一个巨大的列表,然后将该列表对象转换为字典。没有必要使用[..]列表理解;只需删除[]就可以将其转换为内存效率更高的生成器表达式。

  • 您正在使用dict()循环而不是{keyexpr: valueexpr for ... in ...}词典理解;这样可以完全避免生成器表达,直接建立字典。

  • 您正在使用list.count(),这会为每个元素执行列表的完整扫描。您进行了线性扫描,将N个项目计入O(N ** 2)二次问题。每次发现密钥已存在时,您只需在字典中递增一个整数,否则将值设置为0,但有更好的选项(见下文)。

  • sorted()电话正忙着工作;它返回一个排序的键列表,然后再次丢弃。字典不是可排序的,不会以任何速度再次生成字典。

在这里使用collections.Counter() object来计算;它使用线性扫描:

from collections import Counter

dict_pronoun = Counter(lst_all_tweet_noun)

Counter有一个Counter.most_common() method,可以有效地为您输出按计数排序,这是我怀疑您希望通过sorted()调用实现的

例如,要获取前K个元素(其中K小于N,字典的大小),使用heapq在O(NlogK)时间内获取这些元素(避免完整O(NlogN)排序)。