叮咚~发现了个宝藏男孩——collections中的Counter对象!
它可以给我们提供快速和方便的计数,下边我们来做个对比:
先来看看一般情况下我们计算列表中各个元素出现的次数的用法:
a = [1, 1, 1, 2, 2, 3]
b = {}
for i in a:
if i not in b:
b[i] = 1
else:
b[i]+=1
print(b)
运行结果: {1: 3, 2: 2, 3: 1}
再来看看借用Counter时:
# 导入包裹
from collections import Counter
a = [1, 1, 1, 2, 2, 3]
b = Counter()
for i in a:
b[i] += 1
print(b)
运行结果: Counter({1: 3, 2: 2, 3: 1})
这样节约两行代码~
可能有的人会说,啊这也没啥啊,那我们就:
from collections import Counter
a = [1, 1, 1, 2, 2, 3]
print(Counter(a))
运行结果: Counter({1: 3, 2: 2, 3: 1})
三行!只要三行!
它不仅可以运用于列表的计数,字符串也是okk的呢:
from collections import Counter
a = "xiao"
print(Counter(a))
运行结果: Counter({'x': 1, 'i': 1, 'a': 1, 'o': 1})
是不是贼方便!!
这里给大家附上官方文档中,对于它的解释:
一个 Counter 是一个 dict 的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数。 Counter 类有点像其他语言中的 bags或multisets。
意思就是dict可以的它也可(除了fromkeys方法和update方法)
而dict不可以的它可以,比如当我们查询一个不在字典中的键时:
a = [1, 1, 1, 2, 2, 3]
b = {}
for i in a:
if i not in b:
b[i] = 1
else:
b[i]+=1
print(b[4])
运行结果:KeyError: 4
而用Counter:
from collections import Counter
a = [1, 1, 1, 2, 2, 3]
b = Counter()
for i in a:
b[i] += 1
print(b[4])
运行结果: 0
使用Counter对象时,如果引用的键没有任何记录,就返回一个0,而不是弹出一个 KeyError(妙啊)
它还有别的dict没有的功能! 比如most_common方法:
Counter('abracadabra').most_common(3)
运行结果: [('a', 5), ('b', 2), ('r', 2)]
该方法返回一个列表,其中包含 n 个最常见的元素及出现次数,按常见程度由高到低排序。 如果 n 被省略或为 None,most_common() 将返回计数器中的所有元素。
以及subtract方法:
a = Counter({"a":4,"b":3})
b = Counter({"a":2,"b":4,"c":0})
a.subtract(b)
print(a)
运行结果: Counter({'a': 2, 'c': 0, 'b': -1})
该方法是从迭代对象 或映射对象减去元素,输入和输出都可以是0或者负数,但是如果是直接加减,比如这样:
a = Counter({"a":4,"b":3})
b = Counter({"a":2,"b":-4,"c":0})
print(a + b)
运算结果:Counter({'a': 6})
它可以加也可以减,但是输出的结果会忽略掉结果为零或者小于零的计数。
当然也可以使用交集和并集:
a = Counter({"a":4,"b":3})
b = Counter({"a":2,"b":-4,"c":0})
print(a&b)
print(a|b)
运行结果:
Counter({'a': 2}) # intersection: min(a[x], b[x])
Counter({'a': 4, 'b': 3}) # union: max(c[x], d[x])
还有个方法elements:
c = Counter(a=4, b=2, c=0, d=-2)
sorted(c.elements())
运行结果: ['a', 'a', 'a', 'a', 'b', 'b']
该方法返回一个迭代器,其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于1(也就是负无穷大到0),elements() 将会忽略它。