web-dev-qa-db-fra.com

Comment trouver les éléments les plus communs d'une liste?

Compte tenu de la liste suivante

['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.', '']

J'essaie de compter combien de fois chaque mot apparaît et d'afficher le top 3.

Cependant, je ne cherche que les trois premiers qui ont la première lettre en majuscule et ignorent tous les mots sans la première lettre en majuscule.

Je suis sûr qu'il existe un meilleur moyen que celui-ci, mais mon idée était la suivante:

  1. mettre le premier mot de la liste dans une autre liste appelée uniquewords
  2. supprimer le premier mot et tous ses doublons de la liste d'origine
  3. ajouter le nouveau premier mot en mots uniques
  4. supprimer le premier mot et tous ses doublons de la liste d'origine.
  5. etc...
  6. jusqu'à ce que la liste originale soit vide ....
  7. compter combien de fois chaque mot dans uniquewords apparaît dans la liste d'origine
  8. trouver le top 3 et imprimer
27
user434180

Si vous utilisez une version antérieure de Python ou si vous avez une très bonne raison de lancer votre propre compteur Word (j'aimerais l'entendre!), Vous pouvez essayer l'approche suivante en utilisant une 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 Astuce : L’interprète Python interactif est votre ami lorsque vous souhaitez jouer avec un algorithme comme celui-ci. Il suffit de le taper et de le regarder partir, en inspectant les éléments le long du chemin.

15
Johnsyweb

Dans Python 2.7 et les versions ultérieures, il existe une classe appelée Counter qui peut vous aider:

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)

Résultat:

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

Je suis assez nouveau en programmation, alors essayez-le de la manière la plus simple.

Pour ce faire, vous pouvez utiliser un dictionnaire dont la clé est un mot et la valeur est le nombre pour ce mot. Commencez par parcourir les mots en les ajoutant au dictionnaire s'ils ne sont pas présents, ou en augmentant le nombre de mots pour le mot s'il est présent. Ensuite, pour trouver les trois premiers, vous pouvez soit utiliser un algorithme de tri O(n*log(n)) simple et prendre les trois premiers éléments du résultat, soit utiliser un algorithme O(n) qui analyse la liste une fois en ne retenant que les trois premiers.

Une observation importante pour les débutants est qu’en utilisant des classes intégrées conçues à cet effet, vous épargnerez beaucoup de travail et/ou de meilleures performances. Il est bon de se familiariser avec la bibliothèque standard et les fonctionnalités qu’elle offre.

62
Mark Byers

Pour simplement renvoyer une liste contenant les mots les plus courants:

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

ceci imprime:

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

le 3 dans "most_common(3)", spécifie le nombre d'éléments à imprimer. Counter(words).most_common() renvoie une liste de tuples, chaque tuple ayant le mot en tant que premier membre et la fréquence en tant que second membre. Les tuples sont classés en fonction de la fréquence du mot.

`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", extrait uniquement le premier membre du tuple.

13
unlockme

nltk est pratique pour beaucoup de choses sur le traitement du langage. Il possède des méthodes de distribution de fréquence intégrées. Quelque chose comme:

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
mmmdreg

Le code suivant est une solution simple à deux lignes, qui ne nécessite aucun module supplémentaire:

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]

Sortie:

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

Le terme entre crochets renvoie toutes les chaînes uniques de la liste, qui ne sont pas vides et commencent par une lettre majuscule. La fonction sorted() les trie ensuite en fonction de leur fréquence d'apparition dans la liste (à l'aide de la touche lst.count) dans l'ordre inverse. 

2
Chrigi

La réponse de @Mark Byers est la meilleure, mais si vous utilisez une version de Python <2.7 (mais au moins 2.5, ce qui est assez ancien de nos jours), vous pouvez répliquer très simplement les fonctionnalités de la classe Counter via defaultdict (sinon, pour python <2.5, trois lignes de code supplémentaires sont nécessaires avant d [i] + = 1, comme dans la réponse de @ 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]

Ensuite, vous utilisez la classe exactement comme dans la réponse de Mark Byers, à savoir:

words_to_count = (Word for Word in Word_list if Word[:1].isupper())
c = Counter(words_to_count)
print c.most_common(3)
1
JJC

La manière simple de faire cela serait (en supposant que votre liste est en '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')]

Échantillon complet:

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

Par simple, je veux dire travailler dans presque toutes les versions de python.

si vous ne comprenez pas certaines des fonctions utilisées dans cet exemple, vous pouvez toujours le faire dans l'interpréteur (après avoir collé le code ci-dessus):

>>> help(counter.get)
>>> help(sorted)
1
jvdneste

Si vous utilisez Compte , ou avez créé votre propre dictée de style Compte - et souhaitez afficher le nom de l'élément et son compte, vous pouvez effectuer une itération autour du dictionnaire comme suit:

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]

ou pour parcourir ceci dans un modèle:

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

J'espère que cela aide quelqu'un

0
drew