如何找到列表中最常见的元素? [复制]

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

【讨论】:

以上是关于如何找到列表中最常见的元素? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何找到最接近某个数字的数组元素? [复制]

如何在自定义链表实现中找到最常见的元素?

查找字符串数组中最常见的元素 GO

查找列表中不常见的元素

数据结构——数组

将每个列表编号四舍五入到另一个列表中最接近的编号