Лучший способ превратить список слов в частоту - PullRequest
13 голосов
/ 06 апреля 2009

Как лучше всего преобразовать список / кортеж в диктовку, где ключи - это отдельные значения списка, а значения - частоты этих различных значений?

Другими словами:

['a', 'b', 'b', 'a', 'b', 'c']
--> 
{'a': 2, 'b': 3, 'c': 1}

(мне приходилось делать что-то подобное вышеописанному много раз, есть ли в стандартной библиотеке что-нибудь, что делает это для вас?)

EDIT:

Джейкоб Габриельсон отмечает, что в стандартной библиотеке lib для ветки 2.7 / 3.1

что-то есть

Ответы [ 8 ]

29 голосов
/ 06 апреля 2009

Я считаю, что самый простой для понимания (хотя и не самый эффективный) способ это сделать:

{i:words.count(i) for i in set(words)}
20 голосов
/ 06 апреля 2009

Вид

from collections import defaultdict
fq= defaultdict( int )
for w in words:
    fq[w] += 1

Это обычно хорошо работает.

9 голосов
/ 08 апреля 2009

Просто обратите внимание, что начиная с Python 2.7 / 3.1 эта функциональность будет встроена в модуль collections, см. эту ошибку для получения дополнительной информации. Вот пример из заметок о выпуске :

>>> from collections import Counter
>>> c=Counter()
>>> for letter in 'here is a sample of english text':
...   c[letter] += 1
...
>>> c
Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2,
'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1,
'p': 1, 'r': 1, 'x': 1})
>>> c['e']
5
>>> c['z']
0
2 голосов
/ 02 июля 2018

На самом деле ответ Counter уже упоминался, но мы можем даже лучше (проще)!

from collections import Counter
my_list = ['a', 'b', 'b', 'a', 'b', 'c']
Counter(my_list)  # returns a Counter, dict-like object
>> Counter({'b': 3, 'a': 2, 'c': 1})
2 голосов
/ 06 апреля 2009

Это мерзость, но:

from itertools import groupby
dict((k, len(list(xs))) for k, xs in groupby(sorted(items)))

Я не могу придумать причину, по которой этот метод можно было бы выбрать вместо метода С. Лотта, но если кто-то собирается указать на это, это может быть и я. :)

1 голос
/ 10 февраля 2017

Я решил пойти дальше и протестировать предложенные версии, я обнаружил, что collections.Counter, предложенный Джейкобом Габриэльсоном, является самым быстрым, за которым следует defaultdict версия SLott.

Вот мои коды: из коллекции импорта defaultdict из коллекции импорт Счетчик

import random

# using default dict
def counter_default_dict(list):
    count=defaultdict(int)
    for i in list:
        count[i]+=1
    return count

# using normal dict
def counter_dict(list):
    count={}
    for i in list:
        count.update({i:count.get(i,0)+1})
    return count

# using count and dict
def counter_count(list):
    count={i:list.count(i) for i in set(list)}
    return count

# using count and dict
def counter_counter(list):
    count = Counter(list)
    return count

list=sorted([random.randint(0,250) for i in range(300)])


if __name__=='__main__':
    from timeit import timeit
    print("collections.Defaultdict ",timeit("counter_default_dict(list)", setup="from __main__ import counter_default_dict,list", number=1000))
    print("Dict",timeit("counter_dict(list)",setup="from __main__ import counter_dict,list",number=1000))
    print("list.count ",timeit("counter_count(list)", setup="from __main__ import counter_count,list", number=1000))
    print("collections.Counter.count "timeit("counter_counter(list)", setup="from __main__ import counter_counter,list", number=1000))

И мои результаты:

collections.Defaultdict 
0.06787874956330614
Dict
 0.15979115872995675
list.count 
 1.199258431219126
collections.Counter.count
 0.025896202538920665

Дайте мне знать, как я могу улучшить анализ.

1 голос
/ 06 апреля 2009

Я должен поделиться интересным, но довольно нелепым способом сделать это, который я только что придумал:

>>> class myfreq(dict):
...     def __init__(self, arr):
...         for k in arr:
...             self[k] = 1
...     def __setitem__(self, k, v):
...         dict.__setitem__(self, k, self.get(k, 0) + v)
... 
>>> myfreq(['a', 'b', 'b', 'a', 'b', 'c'])
{'a': 2, 'c': 1, 'b': 3}
0 голосов
/ 17 ноября 2018

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

l = [1,4,2,1,2,6,8,2,2]
d ={}
for i in l:
    if i in d.keys():
        d[i] = 1 + d[i]
    else:
        d[i] = 1
print (d)

ор

{1: 2, 4: 1, 2: 4, 6: 1, 8: 1}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...