Как добраться, уникальные значения с соответствующим возникновением рассчитывают из списка в Python?

У меня есть список, который имеет повторяющиеся объекты, и я хочу список уникальных объектов с их частотой.

Например, я имею ['a', 'a', 'b', 'b', 'b'], и я хочу [('a', 2), ('b', 3)].

Поиск простого способа сделать это без цикличного выполнения дважды.

32
задан jpp 23 October 2018 в 08:44
поделиться

7 ответов

Если ваши элементы сгруппированы (т. Е. Похожие элементы объединяются в группу), наиболее эффективным методом является itertools.groupby :

>>> [(g[0], len(list(g[1]))) for g in itertools.groupby(['a', 'a', 'b', 'b', 'b'])]
[('a', 2), ('b', 3)]
11
ответ дан 27 November 2019 в 19:56
поделиться

With Python 2.7+, вы можете использовать collections.Counter .

В противном случае см. этот прием счетчика .

В Python 2.7 +:

from collections import Counter
input =  ['a', 'a', 'b', 'b', 'b']
c = Counter( input )

print( c.items() )

Вывод:

[('a', 2), ('b ', 3)]

63
ответ дан 27 November 2019 в 19:56
поделиться

"старый школьный способ".

>>> alist=['a', 'a', 'b', 'b', 'b']
>>> d={}
>>> for i in alist:
...    if not d.has_key(i): d[i]=1  #also: if not i in d
...    else: d[i]+=1
...
>>> d
{'a': 2, 'b': 3}
3
ответ дан 27 November 2019 в 19:56
поделиться
>>> mylist=['a', 'a', 'b', 'b', 'b']
>>> [ (i,mylist.count(i)) for i in set(mylist) ]
[('a', 2), ('b', 3)]
9
ответ дан 27 November 2019 в 19:56
поделиться

Другой способ сделать это -

mylist = [1, 1, 2, 3, 3, 3, 4, 4, 4, 4]
mydict = {}
for i in mylist:
    if i in mydict: mydict[i] += 1
    else: mydict[i] = 1

затем получить список кортежей,

mytups = [(i, mydict[i]) for i in mydict]

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

Тем не менее, я признаю, что это не очень красивый или краткий фрагмент кода.

1
ответ дан 27 November 2019 в 19:56
поделиться

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

>>> from collections import defaultdict
>>> l = ['a', 'a', 'b', 'b', 'b']
>>> d = defaultdict(int)
>>> for i in l:
...  d[i] += 1
... 
>>> d
defaultdict(<type 'int'>, {'a': 2, 'b': 3})
>>> list(d.iteritems())
[('a', 2), ('b', 3)]
>>>
2
ответ дан 27 November 2019 в 19:56
поделиться

Решение без хеширования:

def lcount(lst):
   return reduce(lambda a, b: a[0:-1] + [(a[-1][0], a[-1][1]+1)] if a and b == a[-1][0] else a + [(b, 1)], lst, [])

>>> lcount([])
[]
>>> lcount(['a'])
[('a', 1)]
>>> lcount(['a', 'a', 'a', 'b', 'b'])
[('a', 3), ('b', 2)]
1
ответ дан 27 November 2019 в 19:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: