从collection.Counter一路追查到__missing__的用法

https://www.liaoxuefeng.com/wiki/1016959663602400/1017681679479008
原文介绍了collection中一些集合类

Counter
Counter是一个简单的计数器,例如,统计字符出现的个数:

>>> from collections import Counter
>>> c = Counter()
>>> for ch in 'programming':
...     c[ch] = c[ch] + 1
...
>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})

Counter实际上也是dict的一个子类,上面的结果可以看出,字符’g’、‘m’、'r’各出现了两次,其他字符各出现了一次。

讨论中有如下内容

这段的for循环是想表达什么意思啊?
寻悲作乐 created at August 20, 2018 8:42 PM, Last updated at June 15, 2019 2:43 PM

from collections import Counter c = Counter() for ch in 'programming': ... c[ch] = c[ch] + 1 ... c Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})

直接调用Counter(‘programming’)也可以,看了下官方文档,元素作key,出现次数是value。所以c[ch]的初始值都是0吗?

直接把我的回复贴过来好了

Counter是个继承自dict的类 但是他们的方法是不同的

可以自己查看一下 哪些是Counter有而dict没有的方法(以及反过来 示例如下)(后记追加:注意__missing__)

>>> [x for x in Counter.__dict__.keys() if x not in dict.__dict__.keys()]
['__module__', '__missing__', 'most_common', 'elements', 'subtract', '__reduce__', '__add__', '__sub__', '__or__', '__and__', '__pos__', '__neg__', '_keep_positive', '__iadd__', '__isub__', '__ior__', '__iand__', '__dict__', '__weakref__']

>>> [y for y in dict.__dict__.keys() if y not in Counter.__dict__.keys()]
['__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__len__', '__getitem__', '__setitem__', '__contains__', '__new__', '__sizeof__', 'get', 'setdefault', 'pop', 'popitem', 'keys', 'items', 'values', 'clear']

针对c[ch] 本来dict是有__getitem__方法的 继承自dict的Counter类自然也有

至于为什么返回不一样(dict[key]对于不存在的key会raise KeyError Counter[key]则不会)

查看collections文件夹下的__init__.py 搜索Counter 其中有如下段落

def __missing__(self, key):
        'The count of elements not in the Counter is zero.'
        # Needed so that self[missing_item] does not raise KeyError
        return 0

因为魔法方法__missing__的存在 在dict中 __getitem__本该raise KeyError的情况 在Counter类则返回0 符合计数器的要求

(这个__missing__的作用我也是刚知道 立刻用自定义类试验了下 底层实现方式先不提 效果的确是这样)

追加:自己的部分测试代码

>>> def ms(self,key):
	return 0

>>> dict.__missing__ = ms
Traceback (most recent call last):
  File "<pyshell#84>", line 1, in <module>
    dict.__missing__ = ms
TypeError: can't set attributes of built-in/extension type 'dict'
>>> class dictt(dict):
	__missing__ = ms

	
>>> test1 = dictt()
>>> test1.__class__
<class '__main__.dictt'>
>>> test1
{}
>>> test1[3]
0
>>> test2 = dict()
>>> test2[3]
Traceback (most recent call last):
  File "<pyshell#96>", line 1, in <module>
    test2[3]
KeyError: 3
>>> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值