其他的字典类型
这些字典类型都市在collections 标准模块中主要有如下:
- 前面见过的:defaultdict 用来处理不存在键
- OrderedDict:用来保持顺序的
- ChainMap:用来容纳个数不同的映射对象
- Counter:用来计数
- UserDict:方便用户自定义自己的映射类型
OrderedDict 与ChainMap
OrderedDict
在添加键的时候会保持顺序,因此键的迭代次序总是一致的。所以如果使用popitem 方法删除的时候字典里最后一个元素。
ChainMap
该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止。
Counter
每次更新一个键的时候都会增加这个计数器。这个类型可以用来计数。或者可以用来计算集合里面元素出现的个数。
- most_common([n]) 返回映射里面最常见的n个键和它们的计数
from collections import Counter
ct = Counter('absdfsfsawefsvlev')
print(ct)
ct.update('aaaaabbbbbccccc')
print(ct)
print(ct.most_common(3))
Counter({'s': 4, 'f': 3, 'a': 2, 'e': 2, 'v': 2, 'l': 1, 'w': 1, 'b': 1, 'd': 1})
Counter({'a': 7, 'b': 6, 'c': 5, 's': 4, 'f': 3, 'e': 2, 'v': 2, 'l': 1, 'w': 1, 'd': 1})
[('a', 7), ('b', 6), ('c', 5)]
子类化UserDict
一般的建议在自定义的映射类型时,建议使用UserDict作为基类,而不要使用dict。因为使用该类比较方便。
- dict 类中某些方法需要重写
- UserDict 类不是dict的子类,
- UserDict 通过一个data属性来实例化dict,这也是数据最终存放的地方。
- UserDict 的子类就能在实现 setitem 的时候避免不必要的递归
具体coding 如下:
# 继承collections.UserDict
import collections
class StrKeyDict(collections.UserDict):
def __missing__(self,key):
if isinstance(key,str):
raise KeyError(key)
return self[str(key)]
def __contains__(self,key):
return str(key) in self.data
def __setitem__(self,key,item):
self.data[str(key)] = item
# 继承dict
class StrkeyDict0(dict):
def __missing__(self,key):
if isinstance(key,str):
raise KeyError(key)
return self[str(key)]
# 考虑递归的问题
def get(self,key,default=None):
try:
return self[key]
except KeyError:
return default
# 需要 keys 存储格式
def __contains__(self,key):
return key in self.keys() or str(key) in self.keys()
UserDict 几个实用的方法
由于UserDict 继承是MutableMapping,所以可以关注一下以下两个方法:
MutableMapping.update
可以直接使用,在 init 里,让构造方法可以利用传入的各种参数来新建实例。也就是利用self[key] = value来添加新的值,其实就是使用了__setitem__方法
Mapping.get
继承该方法后,可以很方便实现数据的获取。