36

我有一个包含重复项目的列表,我想要一个独特项目及其频率的列表。

例如,我有['a', 'a', 'b', 'b', 'b'],我想要[('a', 2), ('b', 3)]

寻找一种简单的方法来做到这一点而无需循环两次。

4

10 回答 10

68

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

于 2010-03-06T15:20:11.743 回答
15

如果您的项目被分组(即类似的项目聚集在一起),最有效的使用方法是itertools.groupby

>>> [(g[0], len(list(g[1]))) for g in itertools.groupby(['a', 'a', 'b', 'b', 'b'])]
[('a', 2), ('b', 3)]
于 2010-03-06T15:18:04.837 回答
13
>>> mylist=['a', 'a', 'b', 'b', 'b']
>>> [ (i,mylist.count(i)) for i in set(mylist) ]
[('a', 2), ('b', 3)]
于 2010-03-06T16:50:05.073 回答
5

如果您愿意使用 3rd 方库,NumPy 提供了一个方便的解决方案。如果您的列表仅包含数字数据,这将特别有效。

import numpy as np

L = ['a', 'a', 'b', 'b', 'b']

res = list(zip(*np.unique(L, return_counts=True)))

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

要理解语法,请注意np.unique此处返回唯一值和计数的元组:

uniq, counts = np.unique(L, return_counts=True)

print(uniq)    # ['a' 'b']
print(counts)  # [2 3]

另请参阅:与常规 Python 列表相比,NumPy 有哪些优势?

于 2018-09-07T15:31:22.007 回答
3

我知道这不是单行的......但对我来说我喜欢它,因为我很清楚我们传递了一次初始值列表(而不是调用 count ):

>>> 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)]
>>>
于 2010-03-06T15:31:06.650 回答
3

“老派的方式”。

>>> 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}
于 2010-03-06T16:34:06.657 回答
1

没有散​​列的解决方案:

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)]
于 2010-03-06T17:28:09.920 回答
1

另一种方法是

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]

这只会遍历列表一次,但它也必须遍历字典一次。但是,鉴于列表中有很多重复项,那么字典应该小很多,因此遍历速度更快。

不过,我承认,这不是一段非常漂亮或简洁的代码。

于 2010-03-06T15:48:21.873 回答
1

将任何数据结构转换为 pandas 系列:

代码:

for i in sort(s.value_counts().unique()):
  print i, (s.value_counts()==i).sum()
于 2015-04-29T20:59:43.137 回答
0

在 pandas 的帮助下,您可以执行以下操作:

import pandas as pd
dict(pd.value_counts(my_list))
于 2018-05-15T10:05:48.430 回答