Python中的项目频率计数
我是一个python新手,所以也许我的问题是很noob。 假设我有一个单词列表,我想查找每个单词出现在列表中的次数。 明显的做法是:
words = "apple banana apple strawberry banana lemon" uniques = set(words.split()) freqs = [(item, words.split.count(item)) for item in uniques] print(freqs)
但是我觉得这个代码不是很好,因为这个程序通过两次单词列表运行,一次build立集合,第二次计算出现次数。 当然,我可以编写一个函数来遍历列表并进行计数,但这不会是pythonic。 那么,有没有更高效的pythonic方法?
defaultdict救援!
from collections import defaultdict words = "apple banana apple strawberry banana lemon" d = defaultdict(int) for word in words.split(): d[word] += 1
这在O(n)中运行。
如果您使用的是Python 2.7 + / 3.1 +,那么collections模块中就有一个Counter类 ,它是专门为解决这类问题而构build的:
>>> from collections import Counter >>> words = "apple banana apple strawberry banana lemon" >>> freqs = Counter(words.split()) >>> print(freqs) Counter({'apple': 2, 'banana': 2, 'strawberry': 1, 'lemon': 1}) >>>
由于2.7和3.1都处于testing阶段,因此不太可能使用它,所以请记住,做这类工作的标准方法很快就可以使用。
标准方法:
from collections import defaultdict words = "apple banana apple strawberry banana lemon" words = words.split() result = collections.defaultdict(int) for word in words: result[word] += 1 print result
Groupby oneliner:
from itertools import groupby words = "apple banana apple strawberry banana lemon" words = words.split() result = dict((key, len(list(group))) for key, group in groupby(sorted(words))) print result
如果你不想使用标准的字典方法(循环列表递增正确的字典键),你可以试试这个:
>>> from itertools import groupby >>> myList = words.split() # ['apple', 'banana', 'apple', 'strawberry', 'banana', 'lemon'] >>> [(k, len(list(g))) for k, g in groupby(sorted(myList))] [('apple', 2), ('banana', 2), ('lemon', 1), ('strawberry', 1)]
它运行在O(n log n)时间。
freqs = {} for word in words: freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize
我认为这个结果与Triptych的解决scheme一样,但是没有导入集合。 也有点像Selinap的解决scheme,但更可读的imho。 与Thomas Weigel的解决scheme几乎相同,但没有使用例外。
这可能比使用集合库中的defaultdict()慢。 由于该值被提取,增加,然后再次分配。 而不是增加。 但是使用+ =可能在内部也是这样。
没有defaultdict:
words = "apple banana apple strawberry banana lemon" my_count = {} for word in words.split(): try: my_count[word] += 1 except KeyError: my_count[word] = 1
你不能只用点数吗?
words = 'the quick brown fox jumps over the lazy gray dog' words.count('z') #output: 1
下面的答案需要一些额外的周期,但这是另一种方法
def func(tup): return tup[-1] def print_words(filename): f = open("small.txt",'r') whole_content = (f.read()).lower() print whole_content list_content = whole_content.split() dict = {} for one_word in list_content: dict[one_word] = 0 for one_word in list_content: dict[one_word] += 1 print dict.items() print sorted(dict.items(),key=func)
我碰巧在一些Spark练习上工作,这里是我的解决scheme。
tokens = ['quick', 'brown', 'fox', 'jumps', 'lazy', 'dog'] print {n: float(tokens.count(n))/float(len(tokens)) for n in tokens}
**#输出上面的**
{'brown': 0.16666666666666666, 'lazy': 0.16666666666666666, 'jumps': 0.16666666666666666, 'fox': 0.16666666666666666, 'dog': 0.16666666666666666, 'quick': 0.16666666666666666}
使用reduce()将列表转换为单个字典。
words = "apple banana apple strawberry banana lemon" reduce( lambda d, c: d.update([(c, d.get(c,0)+1)]) or d, words.split(), {})
回报
{'strawberry': 1, 'lemon': 1, 'apple': 2, 'banana': 2}
words = "apple banana apple strawberry banana lemon" w=words.split() e=list(set(w)) for i in e: print(w.count(i)) #Prints frequency of every word in the list
希望这可以帮助!