2010-08-29 75 views
23

鉴于以下列表如何查找列表的最常见元素?

['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名。

但是我只希望找到前三名有第一个字母大写并忽略没有首字母大写的所有单词。

我肯定有比这更好的办法,但我的想法是要做到以下几点:

  1. 把第一个单词列表进入uniquewords叫
  2. 另一个列表中删除第一个单词所有其复制的原始列表
  3. 将新的第一个单词添加到唯一的单词
  4. 删除第一个单词及其从原始列表中复制的所有。
  5. 等...
  6. 直到原来的列表是空的....
  7. 计数uniquewords每个单词出现了多少次在原始列表
  8. 发现前3名和打印
+0

'help'是不是一个有用的标签。 – SilentGhost 2010-08-29 11:27:17

+0

我喜欢'猫'的参考! – dls 2010-08-29 12:26:56

回答

14

如果您使用的是早期版本的Python,或者您有很好的理由推出自己的word counter(我想听听!),您可以使用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解释器是你的朋友,只要你想用这样的算法玩。只要输入并观看它,检查沿途的元素。

+0

谢谢你这个......但我怎么能这样做,所以它只会查找第一个字母是大写字母,而忽略所有其他字母。 ps。如果一个单词出现多次,有时大写且其他时间不是大写,那么只有当单词的第一个字母是大写字母时才计数。 – user434180 2010-08-29 12:54:57

+1

...然后这听起来很像家庭作业(问题应该标记为这样)。不要将任何以小写字母开头的单词添加到'word_counter'中。如果你更新你的问题,以表明(a)这是一个要求,(b)你自己试图做到这一点,人们更可能提供帮助。 – Johnsyweb 2010-08-29 20:36:29

+0

@Johnsyweb - 在这个相同的话题上,我试图遍历'popular_words'列表来显示单词的名字以及他们旁边的数字......到目前为止,我没有运气,你能指出我在正确的方向?在此先感谢 – drew 2016-11-24 13:13:03

55

在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)] 

I am quite new to programming so please try and do it in the most barebones fashion.

你可以代替做到这一点使用的键是一个字和值是对这个词的计数的字典。首先迭代单词,如果它们不存在,则将它们添加到字典中,否则增加该单词的计数(如果存在)。然后,要找到前三名,您可以使用简单的O(n*log(n))排序算法,并从结果中获取前三个元素,或者您可以使用O(n)算法,该算法只记忆前三个元素,然后扫描列表。

初学者的一个重要观察是,通过使用专为此目的而设计的内建类,您可以节省大量工作和/或获得更好的性能。熟悉标准库和它提供的功能是很好的。

+0

'Counter(lst)'? – SilentGhost 2010-08-29 11:26:28

+0

为什么我得到ImportError(在Python 2.6.1上)? 'ImportError:无法导入名称计数器' – abhiomkar 2010-08-29 16:51:50

+4

@abhiomkar:因为Python 2.6.1不是Python 2.7或更高版本。 – 2010-08-29 18:05:09

1

简单的方式这样做的将(假设你的列表是 '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 
12

如果只想返回包含最常用的单词列表:

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'] 

的3 “most_common(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)]` 

“the word for word, word_counter in”,只提取元组的第一个成员。

+0

是否可以通过most_common函数返回发生次数? – 2017-01-11 01:48:31

+1

是的,几乎是一个初学者,它可以让我编辑答案,告诉你如何 – unlockme 2017-01-27 16:08:26

1

@Mark Byers的答案是最好的,但是如果您使用的是Python的一个版本< 2.7(但至少是2.5,现在已经很老了),您可以通过defaultdict非常简单地复制Counter类的功能否则,对于python < 2.5,在d [i] + = 1之前需要三行额外的代码,如在@ Johnnysweb的答案中)。

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] 

然后,您可以使用类完全按照马克拜尔斯的答案,即:

words_to_count = (word for word in word_list if word[:1].isupper()) 
c = Counter(words_to_count) 
print c.most_common(3) 
1

一个简单的,两行解决这一点,它不需要任何额外的模块是下面的代码:

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键)按相反顺序对它们进行排序。

0

如果您正在使用计数,或者已经创建了自己的计数式的字典,并要显示的项目名称和它的数量,你可以遍历周围的字典,像这样:

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 %} 

希望这可以帮助别人

3

难道光是它只是这个....

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)]