Подтвердить что ты не робот

Как найти наиболее распространенные элементы списка?

Учитывая следующий список

['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 и распечатайте
4b9b3361

Ответ 1

Если вы используете более раннюю версию 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 - ваш друг, когда вы хотите играть с таким алгоритмом. Просто введите его и посмотрите, как он идет, проверяя элементы на этом пути.

Ответ 2

В 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), который сканирует список, запоминая только три верхних элемента.

Важным замечанием для новичков является то, что, используя встроенные классы, предназначенные для этой цели, вы можете сэкономить много работы и/или получить лучшую производительность. Хорошо быть знакомым со стандартной библиотекой и функциями, которые она предлагает.

Ответ 3

Чтобы просто вернуть список, содержащий наиболее распространенные слова:

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

"word for word, word_counter in", извлекает только первый член кортежа.

Ответ 4

Разве это просто...

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

Ответ 5

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

Ответ 6

Простым, двухстрочным решением для этого, которое не требует дополнительных модулей, является следующий код:

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) в обратном порядке.

Ответ 7

Простой способ сделать это будет (если ваш список находится в '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)

Ответ 8

Ответ от @Mark Byers лучше всего, но если вы используете версию Python < 2.7 (но не менее 2,5, что в наши дни довольно устарело), ​​вы можете просто реплицировать функциональность класса Counter через defaultdict (в противном случае для 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)

Ответ 9

Если вы используете Count или создали свой собственный стиль Count-style и хотите показать имя элемента и его количество, вы можете перебирать вокруг словаря так:

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

Надеюсь, это поможет кому-то

Ответ 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(2)  # 2, 3
(most_common_1, count_1), (most_common_2, count_2) = Counter([3, 2, 2]).most_common(2)  # (2, 2), (3, 1)
  • Может возвращать несколько наиболее частых значений
  • Также возвращает количество элементов

Таким образом, в случае вопроса, второй будет правильным выбором. Как примечание стороны, оба идентичны с точки зрения работы.