如何找到列表中最常见的元素? [复制]
Posted
技术标签:
【中文标题】如何找到列表中最常见的元素? [复制]【英文标题】:How to find most common elements of a list? [duplicate] 【发布时间】:2011-04-05 09:40:29 【问题描述】:给定以下列表
['Jellicle', 'Cats', 'are', 'black', 'and', 'white,', 'Jellicle', 'Cats',
'are', 'rather', 'small;', 'Jellicle', 'Cats', 'are', 'merry', 'and',
'bright,', 'And', 'pleasant', 'to', 'hear', 'when', 'they', 'caterwaul.',
'Jellicle', 'Cats', 'have', 'cheerful', 'faces,', 'Jellicle', 'Cats',
'have', 'bright', 'black', 'eyes;', 'They', 'like', 'to', 'practise',
'their', 'airs', 'and', 'graces', 'And', 'wait', 'for', 'the', 'Jellicle',
'Moon', 'to', 'rise.', '']
我正在尝试计算每个单词出现的次数并显示前 3 个。
但是,我只想找到首字母大写的前三个单词,而忽略所有首字母大写的单词。
我确信有比这更好的方法,但我的想法是执行以下操作:
-
将列表中的第一个单词放入另一个名为 uniquewords 的列表中
从原始列表中删除第一个单词及其所有重复项
将新的第一个单词添加到唯一单词中
从原始列表中删除第一个单词及其所有重复项。
等等……
直到原始列表为空....
计算 uniquewords 中每个单词在原始列表中出现的次数
查找前 3 个并打印
【问题讨论】:
然而,这不是其他问题的重复,因为其他问题 (statistics.mode
) 的某些解决方案无法解决此问题。
【参考方案1】:
在 Python 2.7 及更高版本中,有一个名为 Counter 的类可以帮助您:
from collections import Counter
words_to_count = (word for word in word_list if word[:1].isupper())
c = Counter(words_to_count)
print c.most_common(3)
结果:
[('Jellicle', 6), ('Cats', 5), ('And', 2)]
我对编程很陌生,所以请尝试以最简单的方式进行。
您可以改为使用字典来执行此操作,其中键是单词,值是该单词的计数。如果单词不存在,则首先迭代将它们添加到字典中的单词,或者如果单词存在则增加单词的计数。然后要找到前三个,您可以使用简单的O(n*log(n))
排序算法并从结果中取出前三个元素,或者您可以使用O(n)
算法扫描列表一次,只记住前三个元素。
对于初学者的一个重要观察是,通过使用专为此目的设计的内置类,您可以节省大量工作和/或获得更好的性能。熟悉标准库及其提供的功能是件好事。
【讨论】:
为什么我会收到 ImportError(在 Python 2.6.1 上)?ImportError: cannot import name Counter
@abhiomkar:因为 Python 2.6.1 不是 Python 2.7 或更高版本。
谢谢!在我的 Mac 中升级到 Python 2.7。
如果您的 python 小于 2.7,但您想对代码进行未来验证并使用类似 Counter 的类,请参阅下面的答案。 ***.com/a/21760074/379037【参考方案2】:
如果您使用的是较早版本的 Python,或者您有充分的理由推出自己的字数计数器(我想听听!),您可以使用 dict
尝试以下方法。
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> word_list = ['Jellicle', 'Cats', 'are', 'black', 'and', 'white,', 'Jellicle', 'Cats', 'are', 'rather', 'small;', 'Jellicle', 'Cats', 'are', 'merry', 'and', 'bright,', 'And', 'pleasant', 'to', 'hear', 'when', 'they', 'caterwaul.', 'Jellicle', 'Cats', 'have', 'cheerful', 'faces,', 'Jellicle', 'Cats', 'have', 'bright', 'black', 'eyes;', 'They', 'like', 'to', 'practise', 'their', 'airs', 'and', 'graces', 'And', 'wait', 'for', 'the', 'Jellicle', 'Moon', 'to', 'rise.', '']
>>> word_counter =
>>> for word in word_list:
... if word in word_counter:
... word_counter[word] += 1
... else:
... word_counter[word] = 1
...
>>> popular_words = sorted(word_counter, key = word_counter.get, reverse = True)
>>>
>>> top_3 = popular_words[:3]
>>>
>>> top_3
['Jellicle', 'Cats', 'and']
重要提示:只要您想使用这样的算法,交互式 Python 解释器就是您的朋友。只需输入并观察它,一路检查元素。
【讨论】:
谢谢你……但我怎么能这样做,所以它只查找第一个字母为大写字母的单词,而忽略所有其他单词。附言。如果一个单词出现多次,有时大写,有时不大写,则只计算单词首字母为大写的实例。 ...那么这听起来很像家庭作业(问题应该这样标记)。不要在word_counter
中添加任何以小写字母开头的单词。如果您更新您的问题以表明 (a) 这是一项要求,并且 (b) 您已尝试自己执行此操作,那么人们更有可能提供帮助。
@Johnsyweb - 在同一主题上,我正在尝试遍历“popular_words”列表以显示单词的名称以及它们旁边的计数......我没有到目前为止的运气,你能指出我正确的方向吗?提前致谢
@andrew_ : ***.com/a/3594522/78845 似乎就是这样做的。【参考方案3】:
简单的方法是(假设您的列表在“l”中):
>>> counter =
>>> for i in l: counter[i] = counter.get(i, 0) + 1
>>> sorted([ (freq,word) for word, freq in counter.items() ], reverse=True)[:3]
[(6, 'Jellicle'), (5, 'Cats'), (3, 'to')]
完整示例:
>>> l = ['Jellicle', 'Cats', 'are', 'black', 'and', 'white,', 'Jellicle', 'Cats', 'are', 'rather', 'small;', 'Jellicle', 'Cats', 'are', 'merry', 'and', 'bright,', 'And', 'pleasant', 'to', 'hear', 'when', 'they', 'caterwaul.', 'Jellicle', 'Cats', 'have', 'cheerful', 'faces,', 'Jellicle', 'Cats', 'have', 'bright', 'black', 'eyes;', 'They', 'like', 'to', 'practise', 'their', 'airs', 'and', 'graces', 'And', 'wait', 'for', 'the', 'Jellicle', 'Moon', 'to', 'rise.', '']
>>> counter =
>>> for i in l: counter[i] = counter.get(i, 0) + 1
...
>>> counter
'and': 3, '': 1, 'merry': 1, 'rise.': 1, 'small;': 1, 'Moon': 1, 'cheerful': 1, 'bright': 1, 'Cats': 5, 'are': 3, 'have': 2, 'bright,': 1, 'for': 1, 'their': 1, 'rather': 1, 'when': 1, 'to': 3, 'airs': 1, 'black': 2, 'They': 1, 'practise': 1, 'caterwaul.': 1, 'pleasant': 1, 'hear': 1, 'they': 1, 'white,': 1, 'wait': 1, 'And': 2, 'like': 1, 'Jellicle': 6, 'eyes;': 1, 'the': 1, 'faces,': 1, 'graces': 1
>>> sorted([ (freq,word) for word, freq in counter.items() ], reverse=True)[:3]
[(6, 'Jellicle'), (5, 'Cats'), (3, 'to')]
简单我的意思是几乎可以在每个版本的 python 中工作。
如果您不了解本示例中使用的某些函数,您可以随时在解释器中执行此操作(粘贴上面的代码后):
>>> help(counter.get)
>>> help(sorted)
【讨论】:
【参考方案4】:nltk 方便很多语言处理的东西。它具有内置的频率分布方法。例如:
import nltk
fdist = nltk.FreqDist(your_list) # creates a frequency distribution from a list
most_common = fdist.max() # returns a single element
top_three = fdist.keys()[:3] # returns a list
【讨论】:
【参考方案5】:只返回一个包含最常用词的列表:
from collections import Counter
words=["i", "love", "you", "i", "you", "a", "are", "you", "you", "fine", "green"]
most_common_words= [word for word, word_count in Counter(words).most_common(3)]
print most_common_words
打印出来:
['you', 'i', 'a']
“most_common(3)
”中的 3,指定要打印的项目数。
Counter(words).most_common()
返回一个元组列表,每个元组以单词为第一个成员,频率为第二个成员。元组按单词的频率排序。
`most_common = [item for item in Counter(words).most_common()]
print(str(most_common))
[('you', 4), ('i', 2), ('a', 1), ('are', 1), ('green', 1), ('love',1), ('fine', 1)]`
“word for word, word_counter in
”,只提取元组的第一个成员。
【讨论】:
是否可以通过most_common函数返回出现次数? 是的,几乎是初学者,它可以,让我编辑答案告诉你如何【参考方案6】:@Mark Byers 的答案是最好的,但是如果您使用的 Python 版本
from collections import defaultdict
class Counter():
ITEMS = []
def __init__(self, items):
d = defaultdict(int)
for i in items:
d[i] += 1
self.ITEMS = sorted(d.iteritems(), reverse=True, key=lambda i: i[1])
def most_common(self, n):
return self.ITEMS[:n]
然后,您完全按照 Mark Byers 的答案使用该课程,即:
words_to_count = (word for word in word_list if word[:1].isupper())
c = Counter(words_to_count)
print c.most_common(3)
【讨论】:
【参考方案7】:一个简单的两行解决方案,不需要任何额外的模块是以下代码:
lst = ['Jellicle', 'Cats', 'are', 'black', 'and','white,',
'Jellicle', 'Cats','are', 'rather', 'small;', 'Jellicle',
'Cats', 'are', 'merry', 'and','bright,', 'And', 'pleasant',
'to','hear', 'when', 'they', 'caterwaul.','Jellicle',
'Cats', 'have','cheerful', 'faces,', 'Jellicle',
'Cats','have', 'bright', 'black','eyes;', 'They', 'like',
'to', 'practise','their', 'airs', 'and', 'graces', 'And',
'wait', 'for', 'the', 'Jellicle','Moon', 'to', 'rise.', '']
lst_sorted=sorted([ss for ss in set(lst) if len(ss)>0 and ss.istitle()],
key=lst.count,
reverse=True)
print lst_sorted[0:3]
输出:
['Jellicle', 'Cats', 'And']
方括号中的项返回列表中所有唯一的字符串,这些字符串不为空并且以大写字母开头。然后sorted()
函数按照它们在列表中出现的频率(通过使用lst.count
键)以相反的顺序对它们进行排序。
【讨论】:
【参考方案8】:如果您正在使用 Count,或者已经创建了自己的 Count 样式的 dict 并且想要显示项目的名称和它的计数,您可以迭代像这样围绕字典:
top_10_words = Counter(my_long_list_of_words)
# Iterate around the dictionary
for word in top_10_words:
# print the word
print word[0]
# print the count
print word[1]
或在模板中迭代:
% for word in top_10_words %
<p>Word: word.0 </p>
<p>Count: word.1 </p>
% endfor %
希望这对某人有所帮助
【讨论】:
【参考方案9】:不就是这样吗....
word_list=['Jellicle', 'Cats', 'are', 'black', 'and', 'white,', 'Jellicle', 'Cats',
'are', 'rather', 'small;', 'Jellicle', 'Cats', 'are', 'merry', 'and',
'bright,', 'And', 'pleasant', 'to', 'hear', 'when', 'they', 'caterwaul.',
'Jellicle', 'Cats', 'have', 'cheerful', 'faces,', 'Jellicle', 'Cats',
'have', 'bright', 'black', 'eyes;', 'They', 'like', 'to', 'practise',
'their', 'airs', 'and', 'graces', 'And', 'wait', 'for', 'the', 'Jellicle',
'Moon', 'to', 'rise.', '']
from collections import Counter
c = Counter(word_list)
c.most_common(3)
应该输出哪个
[('Jellicle', 6), ('Cats', 5), ('are', 3)]
【讨论】:
【参考方案10】:有两种标准库方法可以找到列表中出现频率最高的值:
statistics.mode
:
from statistics import mode
most_common = mode([3, 2, 2, 2, 1, 1]) # 2
most_common = mode([3, 2]) # StatisticsError: no unique mode
如果没有唯一的最频繁值,则引发异常
只返回一个最频繁的值
collections.Counter.most_common
:
from collections import Counter
most_common, count = Counter([3, 2, 2, 2, 1, 1]).most_common(1)[0] # 2, 3
(most_common_1, count_1), (most_common_2, count_2) = Counter([3, 2, 2]).most_common(2) # (2, 2), (3, 1)
可以返回多个最常用的值
也返回元素计数
所以在这个问题的情况下,第二个将是正确的选择。附带说明一下,两者在性能方面是相同的。
【讨论】:
【参考方案11】:我想用python中强大的数组计算模块numpy来回答这个问题。
这里是代码sn-p:
import numpy
a = ['Jellicle', 'Cats', 'are', 'black', 'and', 'white,', 'Jellicle', 'Cats',
'are', 'rather', 'small;', 'Jellicle', 'Cats', 'are', 'merry', 'and',
'bright,', 'And', 'pleasant', 'to', 'hear', 'when', 'they', 'caterwaul.',
'Jellicle', 'Cats', 'have', 'cheerful', 'faces,', 'Jellicle', 'Cats',
'have', 'bright', 'black', 'eyes;', 'They', 'like', 'to', 'practise',
'their', 'airs', 'and', 'graces', 'And', 'wait', 'for', 'the', 'Jellicle',
'Moon', 'to', 'rise.', '']
dict(zip(*numpy.unique(a, return_counts=True)))
输出
'': 1, 'And': 2, 'Cats': 5, 'Jellicle': 6, 'Moon': 1, 'They': 1, 'airs': 1, 'and': 3, 'are': 3, 'black': 2, 'bright': 1, 'bright,': 1, 'caterwaul.': 1, 'cheerful': 1, 'eyes;': 1, 'faces,': 1, 'for': 1, 'graces': 1, 'have': 2, 'hear': 1, 'like': 1, 'merry': 1, 'pleasant': 1, 'practise': 1, 'rather': 1, 'rise.': 1, 'small;': 1, 'the': 1, 'their': 1, 'they': 1, 'to': 3, 'wait': 1, 'when': 1, 'white,': 1
输出在字典对象中,格式为(键,值)对,其中值是特定单词的计数
这个答案是受***上另一个答案启发的,你可以查看here
【讨论】:
以上是关于如何找到列表中最常见的元素? [复制]的主要内容,如果未能解决你的问题,请参考以下文章