非常详细的Python字典高级用法介绍(二)

1、自动处理缺失的键

在字典高级用法(一)中介绍过自动处理缺失的键的第一种方法是使用defaultlist对象,现在我们接着介绍第二种方法,使用__missing__方法。

映射处理缺失键的底层逻辑在于__missing__方法中。dict基类本身没有定义这个方法,但是如果dict子类定义了这个方法,那么dict.__getitem__找不到键时将会调用__missing__方法,不抛出KeyError。示例如下

class DemoDict(dict):  # 继承dict
    def __missing__(self, key):
        if isinstance(key, str):
            raise KeyError(key)  # 检查key是不是str类型,如果是,并且找不到键则抛出异常
        return self[str(key)]  # 将key转成str类型,查找字符串键

    def get(self, key, default=None):
        try:
            return self[key] # get方法委托__getitem__,通过self[key]查找键,让__miss__发挥作用
        except KeyError:
            return default

    def __contains__(self, key):
        return key in self.keys() or str(key) in self.keys()


d = DemoDict([('2', 'two'), ('4', 'four')])
print(d['2'])  # two
print(d[4])  # four
print(d['1'])  # KeyError: '1'
print(d.get('2'))  # two
print(d.get('4'))  # four
print(d.get('1'))  # None
print(d.get('1', 'N/A'))  # N/A

讲到这里,大概明白字典通过key获取value的底层工作流程了吧,其实这里用户自定义映射类型最好继承collections.UserDict类,而不要继承dict类。上面继承dict类是为了说明内置dict.__getitem__方法支持__missing__。

2、dict变体

collections.OrderedDict

自Python 3.6 起,内置的 dict 也保留键的顺序。使⽤ OrderedDict 最主要的原因是编写与早期 Python 版本兼容的代码。 不过,dict 和 OrderedDict 之间还有⼀些差异,Python ⽂档中有说明,摘录如下(根据日常使用频率,顺序有调整)。

  • OrderedDict 的等值检查考虑顺序
  • OrderedDict 的 popitem() 方法签名不同,可通过⼀个可选 参数指定移除哪⼀项。
  • OrderedDict 多了⼀个 move_to_end() ⽅法,便于把元素的位置移到某⼀端。 常规的 dict 主要⽤于执⾏映射操作,插⼊顺序是次要的。
  • OrderedDict 的目的是方便执行重新排序操作,空间利⽤率、 迭代速度和更新操作的性能是次要的。
  • 从算法上看,OrderedDict 处理频繁重新排序操作的效果比 dict 好,因此适合⽤于跟踪近期存取情况(例如在 LRU 缓存 中)。

collections.ChainMap

ChainMap实例存放一组映射,可作为一个整体来搜索。查找操作按照输入映射在构造函数调用中出现的顺序执行,一旦在某个映射中找到指定的键,旋即结束。比如:

d1 = dict(a=1, b=3)
d2 = dict(a=2, b=4, c=6)
from collections import ChainMap

chain = ChainMap(d1, d2)
print(chain['a'])  # 1
print(chain['c'])  # 6

ChainMap实例不复制输入映射,而是存放映射的引用。ChainMap的更新和插入操作只影响第一个输入映射。比如(接上面案例):

chain['c'] = -1
print(d1) # {'a': 1, 'b': 3, 'c': -1}
print(d2) # {'a': 2, 'b': 4, 'c': 6}

collections.Counter

这是一种对键计数的映射。更新现有键,计数随之增加。可用于统计可哈希对象的实例数量,或者作为多重集使用。Counter实现了组合计数的+和-运算,以及其他一些有用的方法,例如most_common([n])。该方法返回一个有序元组列表,对应前n个计数值最大的项及其数量。比如下面使用Counter统计文本中字的数量。

text = "只因你太美你实在是太美"
from collections import Counter

counter = Counter(text)
print(counter)  # Counter({'你': 2, '太': 2, '美': 2, '只': 1, '因': 1, ',': 1, '实': 1, '在': 1, '是': 1})
counter.update('哦贝贝')
print(counter)  # Counter({'你': 2, '太': 2, '美': 2, '贝': 2, '只': 1, '因': 1, '实': 1, '在': 1, '是': 1, '哦': 1})
print(counter.most_common(3))  # [('你', 2), ('太', 2), ('美', 2)]

shelve.Shelf

标准库中的 shelve 模块持久存储字符串键与(以 pickle ⼆进制格式序列化的)Python 对象之间的映射,这部分这里不作太多介绍,感兴趣可以去看Python文档。

 

 

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值