67 votes

Comptage de la fréquence des articles en Python

Supposons que je dispose d'une liste de mots et que je veuille trouver le nombre de fois où chaque mot apparaît dans cette liste.

Une façon évidente de procéder est de le faire :

words = "apple banana apple strawberry banana lemon"
uniques = set(words.split())
freqs = [(item, words.split().count(item)) for item in uniques]
print(freqs)

Mais je trouve que ce code n'est pas très bon, parce que le programme parcourt la liste de mots deux fois, une fois pour construire l'ensemble, et une deuxième fois pour compter le nombre d'apparitions.

Bien sûr, je pourrais écrire une fonction pour parcourir la liste et faire le décompte, mais ce ne serait pas très Pythonique. Existe-t-il donc une méthode plus efficace et plus pythonique ?

1 votes

Pas deux fois, il semble que la complexité soit O(N*N).

0 votes

Vous pouvez être intéressé par : stackoverflow.com/a/20308657/2534876 pour des questions de performance.

146voto

sykora Points 30290

Les Counter classe dans le collections est spécialement conçu pour résoudre ce type de problème :

from collections import Counter
words = "apple banana apple strawberry banana lemon"
Counter(words.split())
# Counter({'apple': 2, 'banana': 2, 'strawberry': 1, 'lemon': 1})

0 votes

Selon le stackoverflow.com/a/20308657/2534876 Cette méthode est la plus rapide sur Python3 mais lente sur Python2.

0 votes

Savez-vous s'il existe un indicateur permettant de convertir ce pourcentage en freq_dict ? Par exemple, 'apple' : .3333 (2/6),

0 votes

@Tommy total = sum(your_counter_object.values()) entonces freq_percentage = {k: v/total for k, v in your_counter_object.items()}

95voto

Triptych Points 70247

verdict par défaut à la rescousse !

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"

d = defaultdict(int)
for word in words.split():
    d[word] += 1

Cette opération s'effectue en O(n).

2 votes

Cette réponse est très ancienne. Utiliser Counter au lieu de cela.

12voto

hopla Points 1105
freqs = {}
for word in words:
    freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize

Je pense que le résultat est le même que la solution de Triptych, mais sans importer de collections. Cela ressemble aussi un peu à la solution de Selinap, mais en plus lisible. Presque identique à la solution de Thomas Weigel, mais sans utiliser les Exceptions.

Cependant, cela pourrait être plus lent que l'utilisation de defaultdict() de la bibliothèque des collections. En effet, la valeur est récupérée, incrémentée puis à nouveau assignée. Au lieu d'être simplement incrémentée. Cependant, l'utilisation de += pourrait faire la même chose en interne.

11voto

nosklo Points 75862

Approche standard :

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"
words = words.split()
result = defaultdict(int)
for word in words:
    result[word] += 1

print result

Groupby oneliner :

from itertools import groupby

words = "apple banana apple strawberry banana lemon"
words = words.split()

result = dict((key, len(list(group))) for key, group in groupby(sorted(words)))
print result

0 votes

Y a-t-il une différence de complexité ? Est-ce que groupby utilise le tri ? Dans ce cas, il semble avoir besoin d'un temps O(nlogn) ?

0 votes

Oups, il semble que Nick Presta ci-dessous ait fait remarquer que l'approche groupby utilise O(nlogn).

7voto

Nick Presta Points 13298

Si vous ne voulez pas utiliser la méthode standard du dictionnaire (boucler la liste en incrémentant la clé dict. appropriée), vous pouvez essayer ceci :

>>> from itertools import groupby
>>> myList = words.split() # ['apple', 'banana', 'apple', 'strawberry', 'banana', 'lemon']
>>> [(k, len(list(g))) for k, g in groupby(sorted(myList))]
[('apple', 2), ('banana', 2), ('lemon', 1), ('strawberry', 1)]

Il s'exécute en O(n log n) temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X