Jak znaleźć najczęstsze elementy listy?

Podano następującą 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.', '']

Próbuję policzyć, ile razy każde słowo pojawia się i wyświetla górną 3.

Jednak Szukam tylko trzech najlepszych, które mają pierwszą literę wielką i ignorują wszystkie słowa, które nie mają pierwszej litery wielkiej litery.

Jestem pewien, że jest lepszy sposób niż ten, ale moim pomysłem było zrobić następujące rzeczy:

  1. Umieść pierwsze słowo z listy w innej liście o nazwie uniquewords
  2. Usuń pierwsze słowo i wszystkie jego duplikaty z oryginalnej listy
  3. dodaj nowe pierwsze słowo do unikalnych słów
  4. Usuń pierwsze słowo i wszystkie jego duplikaty z oryginalnej listy.
  5. itd...
  6. dopóki oryginalna lista nie będzie pusta....
  7. policz, ile razy każde słowo w uniquewords pojawia się na oryginalnej liście
  8. znajdź top 3 i wydrukuj
Author: Andy Lester, 2010-08-29

9 answers

Jeśli używasz wcześniejszej wersji Pythona lub masz bardzo dobry powód, aby rzucić swój własny licznik słów (chciałbym to usłyszeć!), możesz wypróbować następujące podejście używając 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']

Top Tip : interaktywny interpretator Pythona jest twoim przyjacielem, gdy chcesz bawić się algorytmem takim jak ten. Po prostu wpisz go i obserwuj, jak leci, sprawdzając elementy po drodze.

 13
Author: Johnsyweb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-29 12:12:58

W Pythonie 2.7 i wyżej istnieje klasa o nazwie Counter, która może Ci pomóc:

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)

Wynik:

[('Jellicle', 6), ('Cats', 5), ('And', 2)]

Jestem całkiem nowy w programowaniu, więc proszę spróbować i zrobić to w najbardziej barebones Moda.

Zamiast tego możesz to zrobić używając słownika, w którym kluczem jest słowo, a wartością jest Liczba dla tego słowa. Najpierw powtarzaj słowa dodając je do słownika, jeśli nie są obecne, lub zwiększaj liczbę słów jeśli jest obecny. Następnie możesz użyć prostego algorytmu sortowania O(n*log(n)) i pobrać trzy pierwsze elementy z wyniku, lub możesz użyć algorytmu O(n), który skanuje listę po zapamiętaniu tylko trzech pierwszych elementów.

Ważną obserwacją dla początkujących jest to, że korzystając z wbudowanych klas, które są przeznaczone do tego celu, możesz zaoszczędzić sobie dużo pracy i/lub uzyskać lepszą wydajność. Dobrze jest zapoznać się z biblioteką standardową i funkcje, które oferuje.

 60
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-29 18:13:30

Aby po prostu zwrócić listę zawierającą najczęściej używane słowa:

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

To drukuje:

['you', 'i', 'a']

3 W "most_common(3)", określa liczbę elementów do wydrukowania. Counter(words).most_common() zwraca listę krotek, przy czym każda krotka ma słowo jako pierwszy człon, a częstotliwość jako drugi człon.Krotki są uporządkowane według częstotliwości słowa.

`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", wydobywa tylko pierwszy człon krotki.

 13
Author: unlockme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-27 16:24:10

Nltk jest wygodne dla wielu rzeczy przetwarzania języka. Posiada wbudowane metody rozkładu częstotliwości. Coś w stylu:

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
Author: mmmdreg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-17 00:38:46

Nie chodzi tylko o to ....

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)

Który powinien wyjść

[('Jellicle', 6), ('Cats', 5), ('are', 3)]

 4
Author: Tim Seed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-11 07:31:10

Prostym, dwuliniowym rozwiązaniem tego problemu, które nie wymaga żadnych dodatkowych modułów jest następujący kod:

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]

Wyjście:

['Jellicle', 'Cats', 'And']

Termin w nawiasach kwadratowych zwraca wszystkie unikalne ciągi znaków na liście, które nie są puste i rozpoczynają się wielką literą. Funkcja sorted() sortuje je po tym, jak często pojawiają się na liście (używając klawisza lst.count) w odwrotnej kolejności.

 2
Author: Chrigi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-24 11:14:56

W prosty sposób można to zrobić (zakładając, że Twoja lista jest w "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')]

Pełna próbka:

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

Z prostym mam na myśli pracę w prawie każdej wersji Pythona.

Jeśli nie rozumiesz niektórych funkcji użytych w tym przykładzie, zawsze możesz to zrobić w interpreterze (po wklejeniu kodu powyżej):

>>> help(counter.get)
>>> help(sorted)
 1
Author: jvdneste,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-29 12:23:01

Odpowiedź od @Mark Byers jest najlepsza, ale jeśli korzystasz z wersji Pythona

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]

Następnie używasz klasy dokładnie tak, jak w odpowiedzi Marka Byersa, tzn.:

words_to_count = (word for word in word_list if word[:1].isupper())
c = Counter(words_to_count)
print c.most_common(3)
 1
Author: JJC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-13 16:36:35

Jeśli używasz Count , lub stworzyłeś swój własny count -style dict i chcesz pokazać nazwę elementu i jego liczbę, możesz iterację wokół słownika w następujący sposób:

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]

Lub do iteracji w szablonie:

{% for word in top_10_words %}
        <p>Word: {{ word.0 }}</p>
        <p>Count: {{ word.1 }}</p>
{% endfor %}

Hope this helps someone

 0
Author: drew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-01 09:25:02