Pregunta

Supongamos que tengo una lista de palabras, y yo quiero encontrar el número de veces que cada palabra aparece en esa lista.

Una manera obvia de hacerlo 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 este código no es muy bueno, ya que el programa se ejecuta a través de la lista de palabras dos veces, una para construir el conjunto, y una segunda vez para contar el número de apariciones.

Por supuesto, podría escribir una función para ejecutar a través de la lista y hacer el recuento, pero eso no sería tan Pythonic. Por lo tanto, hay una manera más eficiente y Pythonic?

¿Fue útil?

Solución

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

Otros consejos

El Counter clase en el módulo collections está construido a 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})

enfoque estándar:

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"
words = words.split()
result = collections.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
freqs = {}
for word in words:
    freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize

Creo que esto da a los mismos que la solución de tríptico, pero sin importar colecciones. También un poco como solución de Selinap, pero en mi humilde opinión más legible. Casi idéntica a la solución de Thomas Weigel, pero sin el uso de excepciones.

Esto podría ser más lento que usar defaultdict () de la biblioteca de colecciones sin embargo. Dado que el valor es exagerado, incrementado y luego asignado de nuevo. En lugar de simplemente incrementado. Sin embargo el uso de + = podría hacer lo mismo internamente.

Si no desea utilizar el método de diccionario estándar, puede probar este (bucle a través de la lista de incrementar el dict adecuada llave.):

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

Se ejecuta en tiempo O (n log n).

Sin defaultdict:

words = "apple banana apple strawberry banana lemon"
my_count = {}
for word in words.split():
    try: my_count[word] += 1
    except KeyError: my_count[word] = 1

¿No puedes usar la cuenta?

words = 'the quick brown fox jumps over the lazy gray dog'
words.count('z')
#output: 1

Me pasó a trabajar en algo de ejercicio Spark, aquí está mi solución.

tokens = ['quick', 'brown', 'fox', 'jumps', 'lazy', 'dog']

print {n: float(tokens.count(n))/float(len(tokens)) for n in tokens}

** # salida de los anteriores **

{'brown': 0.16666666666666666, 'lazy': 0.16666666666666666, 'jumps': 0.16666666666666666, 'fox': 0.16666666666666666, 'dog': 0.16666666666666666, 'quick': 0.16666666666666666}

Uso reducir () para convertir la lista a un solo dict.

words = "apple banana apple strawberry banana lemon"
reduce( lambda d, c: d.update([(c, d.get(c,0)+1)]) or d, words.split(), {})

retornos

{'strawberry': 1, 'lemon': 1, 'apple': 2, 'banana': 2}
words = "apple banana apple strawberry banana lemon"
w=words.split()
e=list(set(w))       
for i in e:
   print(w.count(i))    #Prints frequency of every word in the list

Espero que esto ayude!

La respuesta a continuación tiene algunos ciclos extra, pero es otro método

def func(tup):
    return tup[-1]


def print_words(filename):
    f = open("small.txt",'r')
    whole_content = (f.read()).lower()
    print whole_content
    list_content = whole_content.split()
    dict = {}
    for one_word in list_content:
        dict[one_word] = 0
    for one_word in list_content:
        dict[one_word] += 1
    print dict.items()
    print sorted(dict.items(),key=func)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top