第3章:字典和集合-字典的变种(OrderedDict、Counter、UserDict、ChainMap)

这一节总结了标准库里 collections 模块中,除了 defaultdict 之外的不同映射类型。

 OrderedDict

  OrderedDict 类型在添加键的时候会保持顺序,因此键的迭代次序总是一致的。OrderedDict 的 popitem 方法默认删除并返回的是字典里的最后一个元素,但是如果像 my_odict.popitem(last=False) 这样调用它,那么它删除并返回第一个被添加进去的元素。

Counter

  Counter 类型会给“键”准备一个整数计数器。每次更新一个“键”的时候都会增加这个计数器。所以这个类型可以用来给可散列表对象计数,或者是当成多重集来用——多重集合就是集合里的元素可以出现不止一次。Counter 实现了 + 和 - 运算符用来合并记录,还有像 most_common([n]) 这类很有用的方法。most_common([n]) 会按照次序返回映射里最常见的 n 个键和它们的计数。

import collections

# 以元素作为 key,以 key 出现的次数来作为 value
st = collections.Counter('abcacababca')
print(st)  # Counter({'a': 5, 'b': 3, 'c': 3})

# 以元素作为 key,以 key 出现的次数来作为 value
lt = collections.Counter(['a', 'b', 'c', 'a', 'c', 'a', 'b', 'a', 'b', 'c', 'a'])
print(lt)  # Counter({'a': 5, 'b': 3, 'c': 3})

# 更新键计数器
st.update('aaaazzzz')
print(st)  # Counter({'a': 9, 'z': 4, 'b': 3, 'c': 3})

# list 可以和 str 一起使用
lt.update('aaaazzzz')
print(lt)  # Counter({'a': 9, 'z': 4, 'b': 3, 'c': 3})

# 合并两个计数器
zt = st + lt
print(zt)  # Counter({'a': 18, 'z': 8, 'b': 6, 'c': 6})

# 返回映射里最常见的 n 个 key 和出现的次数;
z = zt.most_common(2)
print(z)  # [('a', 18), ('z', 8)]

ChainMap

  ChainMap 类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止。这个功能在给有嵌套作用域的语言做解释器的时候很有用,可以用一个映射对象来代表一个作用域的上下文。在 collections 文档介绍 ChainMap 对象的那一部分里有一些具体的使用示例,其中包含了下面这个 Python 变量查询规则的代码片段:

import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))

 

UserDict 

        这个类其实就是把标准 dict 用纯 Python 又实现了一遍。跟 OrderedDict 和 Counter 这些开箱即用的类型不同,UserDict 是让用户继承写子类的。更倾向于从 UserDict 而不是从 dict 继承的主要原因是,后者有时会在某些方法的实现上走一些捷径,导致我们不得不在它的子类中重写这些方法,但是 UserDict 就不会带来这些问题。

示例 3-8 无论是添加、更新还是查询操作,StrKeyDict 都会把非字符串的键转换为字符串

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

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值