06-python中的集合类-02-ChainMap

06-python中的集合类-02-ChainMap

今天 我们继续讲解 Collections 中的 其他的数据结构 ChainMap , 看这个名称 大概也能知道 是做什么的?

就是把多个字典拉成一个Chain的形式。

namedtuple()factory function for creating tuple subclasses with named fields
dequelist-like container with fast appends and pops on either end
ChainMapdict-like class for creating a single view of multiple mappings
Counterdict subclass for counting hashable objects
OrderedDictdict subclass that remembers the order entries were added
defaultdictdict subclass that calls a factory function to supply missing values
UserDictwrapper around dictionary objects for easier dict subclassing
UserListwrapper around list objects for easier list subclassing
UserStringwrapper around string objects for easier string subclassing

ChainMap 的使用

chainmap 就是把一些 字典 放在一个 chain 里面, 逻辑上 感觉 像是一个字典一样使用, 其实内部做了一个 maps 的属性, 把字典放在 一个list 里面了。

ChainMap 的使用场景: 有多个字典或者映射,你想将它们从逻辑上合并为一个单一的映射后执行某些操作

from collections import ChainMap

a = {"x": 1, "z": 3}
b = {"y": 2, "z": 4}
c = {"y": 20, "z": 30, "x": 10, "p": 66}

chain = ChainMap(a, b, c)
print(chain)

在新生成的chain 中 你几乎可以把它当做一个字典使用。 比如 去 chain['x'],chain.get('y')

img-01

这里有一个maps 的属性, 这里就是存放所有的字典的一个list , 当取字典中的key 的时候, 他会先去第一个字典查找 如果有 就直接返回,如果没有就到第二字典里面去找,以此类推,之后找完maps 后都没有, 要么返回None, 要么报错。

举个例子

>>> from collections import ChainMap
>>> chain
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}, {'y': 20, 'z': 30, 'x': 10, 'p': 66})

>>> chain.get('y')
2
>>> chain.get('z')
3
>>> 
>>> 
>>> chain['x']
1
>>> chain['z']
3
>>> chain['name']
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/collections/__init__.py", line 916, in __getitem__
    return self.__missing__(key)            # support subclasses that define __missing__
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/collections/__init__.py", line 908, in __missing__
    raise KeyError(key)
KeyError: 'name'

img-02

当取 key=‘y’ 的时候, 第二字典里有,直接返回。

当取 key=‘z’ 的时候 这三个字典 都有 那么就看谁在前面就取谁。 第一个字典中就有 所以返回是 3 。

ChainMap 只是把字典 逻辑上连接在一起 方便 我们当成一个字典使用。

比如判断 key 是否在 这几个字典中,

ChainMap 删除 增加元素

注意:

于字典的更新或删除操作总是影响的是列表中第一个字典

>>> chain
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}, {'y': 20, 'z': 30, 'x': 10, 'p': 66})
>>> chain['name']='frank'
>>> chain
ChainMap({'x': 1, 'z': 3, 'name': 'frank'}, {'y': 2, 'z': 4}, {'y': 20, 'z': 30, 'x': 10, 'p': 66})


>>> # 删除元素
>>> chain.pop('x')
1
>>> chain
ChainMap({'z': 3, 'name': 'frank'}, {'y': 2, 'z': 4}, {'y': 20, 'z': 30, 'x': 10, 'p': 66})

如果 你想删除 第二个字典的元素 会失败, 比如我想删除,key=‘y’ 的键值对时,就会报错。

>>> chain
ChainMap({'z': 3, 'name': 'frank'}, {'y': 2, 'z': 4}, {'y': 20, 'z': 30, 'x': 10, 'p': 66})
>>> chain.pop('y')
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/collections/__init__.py", line 984, in pop
    return self.maps[0].pop(key, *args)
KeyError: 'y'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/collections/__init__.py", line 986, in pop
    raise KeyError('Key not found in the first mapping: {!r}'.format(key))
KeyError: "Key not found in the first mapping: 'y'"

对于删除 ,增加 键值对 都是对第一个 字典 进行的。 对于查找 是可以 查找所有的字典。

来看下例子

>>> chain
ChainMap({'z': 3, 'name': 'frank'}, {'y': 2, 'z': 4}, {'y': 20, 'z': 30, 'x': 10, 'p': 66})
>>> 'p' in chain
True

查找元素 会安装 chainmap 顺序 去查找, 因为p 是在第三个字典中的,所以返回True

ChainMap 中加入一个新的字典

在chainmap 中加入一个新的字典, 可以使用 new_child 方法 加入一个字典


from collections import ChainMap

one = {'one': 1}
two = {'two': 2}
three = {'three': 3}
chain = ChainMap(one, two)

print(chain)

chain2 = chain.new_child(three)

在控制台里演示一下

>>> from collections import ChainMap
... 
... one = {'one': 1}
... two = {'two': 2}
... three = {'three': 3}
... # four = {'four': 4}
>>> 
>>> 
>>> chain = ChainMap(one, two)
>>> chain
ChainMap({'one': 1}, {'two': 2})
>>> chain.new_child(three)
ChainMap({'three': 3}, {'one': 1}, {'two': 2})

会返回一个chainMap 并且 最新加入的字典会放在 第一个位置,看例子。

ChainMap 中 获取parents

ChainMap 中有一个属性, parents , 用来获取除去第一个位置的元素 后面的 所有元素

>>> from collections import ChainMap
... 
... one = {'one': 1}
... two = {'two': 2}
... three = {'three': 3}
... four = {'four': 4}
... 
... chain = ChainMap(one, two,three,four)
>>> 
>>> 
>>> chain
ChainMap({'one': 1}, {'two': 2}, {'three': 3}, {'four': 4})

>>> chain.parents
ChainMap({'two': 2}, {'three': 3}, {'four': 4})
>>> chain.parents.parents
ChainMap({'three': 3}, {'four': 4})

也就是 以第一个位置是 child , 第二个位置是parent, 第三个位置是 第二位置的parent

image-20200912223022412

总结

​ 本文主要总结 ChainMap 的一些特点, 我平常对这个结构用的比较少。 以后可以多用一下 标准库中提供这个 类型,方便我们提高开发效率。

参考文档

1.20 合并多个字典或映射

ChainMap 官方文档

分享快乐,留住感动.2020-09-12 22:45:17 --frank
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值