Recuento de frecuencia de elementos en Python
Supongamos que tengo una lista de palabras y quiero encontrar la cantidad de veces que aparece cada palabra en esa lista.
Una forma obvia de hacer esto es:
words = "apple banana apple strawberry banana lemon"
uniques = set(words.split())
freqs = [(item, words.split().count(item)) for item in uniques]
print(freqs)
Pero encuentro que este código no es muy bueno, porque el programa recorre la lista de palabras dos veces, una para construir el conjunto y otra para contar el número de apariciones.
Por supuesto, podría escribir una función para recorrer la lista y contar, pero eso no sería tan Pythonic. Entonces, ¿existe una forma más eficiente y pitónica?
La Counter
clase del collections
módulo está diseñada específicamente para resolver este tipo de problema:
from collections import Counter
words = "apple banana apple strawberry banana lemon"
Counter(words.split())
# Counter({'apple': 2, 'banana': 2, 'strawberry': 1, 'lemon': 1})
defaultdict al rescate!
from collections import defaultdict
words = "apple banana apple strawberry banana lemon"
d = defaultdict(int)
for word in words.split():
d[word] += 1
Esto se ejecuta en O(n).
freqs = {}
for word in words:
freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize
Creo que esto resulta igual que la solución de Triptych, pero sin importar colecciones. También un poco como la solución de Selinap, pero más legible en mi humilde opinión. Casi idéntica a la solución de Thomas Weigel, pero sin utilizar Excepciones.
Sin embargo, esto podría ser más lento que usar defaultdict() de la biblioteca de colecciones. Dado que el valor se recupera, se incrementa y luego se asigna nuevamente. En lugar de simplemente incrementarse. Sin embargo, usar += podría hacer lo mismo internamente.
Enfoque estándar:
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
Oneliner grupal:
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