some_data = [ "a ","f", "12", "2","4", 5, 2 ,' b' , 4 , 7, ' a ', 5,'d', 'a', ' z ']
count_frq = dict()
for item in some_data:
if item in count_frq:
count_frq[item]+=1
else:
count_frq[item] = 1
print('结果:', count_frq)
结果: {'a ': 1, 'f': 1, '12': 1, '2': 1, '4': 1, 5: 2, 2: 1, ' b': 1, 4: 1, 7: 1, ' a ': 1, 'd': 1, 'a': 1, ' z ': 1}
from collections import defaultdict
count_frq=defaultdict(int)
for item in some_data:
count_frq[item] += 1
print('结果:',count_frq)
结果: defaultdict(<class 'int'>, {'a ': 1, 'f': 1, '12': 1, '2': 1, '4': 1, 5: 2, 2: 1, ' b': 1, 4: 1, 7: 1, ' a ': 1, 'd': 1, 'a': 1, ' z ': 1})
count_set = set(some_data)
count_list =[]
for item in count_set:
count_list.append ((item,some_data.count(item)))
print (count_list)
[('d', 1), (2, 1), (' b', 1), (4, 1), (5, 2), ('a ', 1), (7, 1), (' a ', 1), ('12', 1), ('f', 1), ('2', 1), ('4', 1), (' z ', 1), ('a', 1)]
上面的方法都比较简单,但有没有更优雅、更 pythonic
的解决方法呢?
答案是使用 collections.Counter()
。
from collections import Counter
print (Counter(some_data))
Counter({5: 2, 'a ': 1, 'f': 1, '12': 1, '2': 1, '4': 1, 2: 1, ' b': 1, 4: 1, 7: 1, ' a ': 1, 'd': 1, 'a': 1, ' z ': 1})
Counter
类是自Python2.7起增加的,属于字典类的子类,是一个容器对象,主要用来统计散列对象。
支持集合操作 +
、 -
、 &
、 |
,
其中 &
和 |
操作分别返回两个 Counter
对象各元素的最小值和最大值。
它提供了 3种不同的方式来初始化:
Counter ("success")
# 可迭代对象Counter (s=3, c=2, e=1, u=1)
# 关键字參教Counter ({'s': 3, "c" :2, "u":1 ,"e": 1})
#字典
可以使用 elements()
方法来获取 Counter
中的 key
值。
list(Counter(some_data).elements())
['a ', 'f', '12', '2', '4', 5, 5, 2, ' b', 4, 7, ' a ', 'd', 'a', ' z ']
利用 most_common()
方法可以找出前 $N$
个出现频率最高的元素以及它们对应的次数。
Counter (some_data).most_common (2)
[(5, 2), ('a ', 1)]
当访问不存在的元素时,默认返回为 0
而并不抛出 KeyError
异常。
(Counter (some_data))['y']
0
update()
方法用于被统计对象元素的更新,原有 Counter
计数器对象与新增元素的统计计数值相加而不是直接替换它们。
subtract()
方法用于实现计数器对象中元素统计值相减,输入和输出的统计值允许为 0
或者负数。
c = Counter ("success")
c.update("successfully")
c
Counter({'s': 6, 'c': 4, 'u': 3, 'e': 2, 'l': 2, 'f': 1, 'y': 1})
c.subtract ("successfulllly")
c
Counter({'s': 3, 'c': 2, 'u': 1, 'e': 1, 'f': 0, 'y': 0, 'l': -2})
from collections import Counter
创建一个空的 Counter
对象:
c1 = Counter()
从一个可迭代对象(列表,元组,字典,字符串)创建:
c2 = Counter('hello world')
c2
Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
从一组键值对创建:
c3 = Counter(a=3, b=4)
c3
Counter({'b': 4, 'a': 3})
只看c2的话,使用字符串的方法不是可以实现相同的功能么?
word = 'hello world'
print(word.count('h')) # 1
1
print(word.count('l')) # 3
3
c1['apple']
0
c1 = Counter('hello world')
c1['o']
2
使用另一个 iterable
对象更新:
c1.update('hello')
c1['o']
3
使用另一个 Counter
对象更新:
c2 = Counter('world')
c1.update(c2)
c1['o']
4
使用 subtract
from collections import Counter
c1 = Counter('hello world')
c1.subtract('hello') # 使用另一个iterable对象更新
print(c1['o']) # 1
1
c2 = Counter('world')
c1.subtract(c2) # 使用另一个Counter对象更新
print(c1['o']) # 0
0
from collections import Counter
c1 = Counter('hello world')
del c1['o']
print(c1['o']) # 0
0
from collections import Counter
c1 = Counter('hello world')
lst = list(c1.elements())
print(lst) # ['h', 'e', 'l', 'l', 'l', 'o', 'o', ' ', 'w', 'r', 'd']
['h', 'e', 'l', 'l', 'l', 'o', 'o', ' ', 'w', 'r', 'd']
from collections import Counter
c1 = Counter('hello world')
print(c1.most_common(2)) # [('l', 3), ('o', 2)]
[('l', 3), ('o', 2)]
from collections import Counter
c = Counter(a=1, b=3)
d = Counter(a=2, b=2)
print(c + d) # Counter({'b': 5, 'a': 3})
Counter({'b': 5, 'a': 3})
print(c - d) # Counter({'b': 1})
Counter({'b': 1})
print(c & d) # Counter({'b': 2, 'a': 1})
Counter({'b': 2, 'a': 1})
print(c | d) # Counter({'b': 3, 'a': 2})
Counter({'b': 3, 'a': 2})