Частота счета предметов в Python - PullRequest
53 голосов
/ 21 мая 2009

Предположим, у меня есть список слов, и я хочу узнать, сколько раз каждое слово появляется в этом списке.

Очевидный способ сделать это:

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

Но я нахожу этот код не очень хорошим, потому что программа запускает список слов дважды, один раз для построения набора и второй для подсчета количества появлений.

Конечно, я мог бы написать функцию для запуска по списку и подсчета, но это не было бы так Pythonic. Итак, есть ли более эффективный и питонский способ?

Ответы [ 11 ]

129 голосов
/ 21 мая 2009

Counter класс в модуле collections специально предназначен для решения этого типа проблемы:

from collections import Counter
words = "apple banana apple strawberry banana lemon"
Counter(words.split())
# Counter({'apple': 2, 'banana': 2, 'strawberry': 1, 'lemon': 1})
93 голосов
/ 21 мая 2009

defaultdict на помощь!

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"

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

Это работает в O (n).

11 голосов
/ 21 мая 2009

Стандартный подход:

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
9 голосов
/ 12 июня 2009
freqs = {}
for word in words:
    freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize

Я думаю, что это приводит к тому же решению, что и в Triptych, но без импорта коллекций Также немного похоже на решение Селинапа, но более читабельное imho. Почти идентичен решению Томаса Вейгеля, но без исключений.

Однако это может быть медленнее, чем использование defaultdict () из библиотеки коллекций. Так как значение извлекается, увеличивается и затем назначается снова. Вместо того, чтобы просто увеличить. Однако использование + = может сделать то же самое внутри.

7 голосов
/ 21 мая 2009

Если вы не хотите использовать стандартный метод словаря (циклически изменяя список, увеличивая правильный ключ dict.), Вы можете попробовать это:

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

Работает за O (n log n).

3 голосов
/ 21 мая 2009

без дефолта:

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
0 голосов
/ 12 ноября 2017
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

Надеюсь, это поможет!

0 голосов
/ 23 февраля 2016

Используйте Reduce (), чтобы преобразовать список в один диктант.

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

возвращает

{'strawberry': 1, 'lemon': 1, 'apple': 2, 'banana': 2}
0 голосов
/ 26 июня 2015

Мне довелось поработать над каким-нибудь упражнением Spark, вот мое решение.

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

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

** # выход вышеупомянутого **

{'brown': 0.16666666666666666, 'lazy': 0.16666666666666666, 'jumps': 0.16666666666666666, 'fox': 0.16666666666666666, 'dog': 0.16666666666666666, 'quick': 0.16666666666666666}
0 голосов
/ 27 февраля 2013

Ответ ниже занимает несколько дополнительных циклов, но это другой метод

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...