前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一日一技:在Python中合并字典模块ChainMap的隐藏坑

一日一技:在Python中合并字典模块ChainMap的隐藏坑

作者头像
青南
发布2019-06-11 19:53:22
1.3K0
发布2019-06-11 19:53:22
举报
文章被收录于专栏:未闻Code未闻Code

在Python中,当我们有两个字典需要合并的时候,可以使用字典的 update方法,例如:

代码语言:javascript
复制
a = {'a': 1, 'b': 2}b = {'x': 3, 'y': 4}a.update(b)print(a)

运行效果如下图所示:

然而,这个方法有一个问题——它会改变其中一个字典。如果我们不想改变原有的两个字典,那么我们必需要单独再创建一个字典:

代码语言:javascript
复制
a = {'a': 1, 'b': 2}b = {'x': 3, 'y': 4}c = dict(a)c.update(b)print(c)print(a)

如果原来的两个字典非常大,那么这种方式将会浪费大量的内存。

无论是直接修改原有的其中一个字典,还是创建另一个字典,这两种方案都有点缺陷。那么有没有既不修改原有字典,又不另外创建一个新的字典的方法呢?

答案就是 collections模块下面的 ChainMap

使用 ChainMap可以把多个字典合并成一个 ChainMap对象。读写这个对象就像是读字典一样。

例如:

代码语言:javascript
复制
from collections import ChainMapa = {'a': 1, 'b': 2}b = {'x': 3, 'y': 4}c = ChainMap(a, b)print(c['a'])print(c['y'])

运行效果如下图所示:

不仅可以“合并”两个字典, ChainMap可以接受任意多个字典,并把他们全都合在一起:

代码语言:javascript
复制
from collections import ChainMapa = {'a': 1, 'b': 2}b = {'x': 3, 'y': 4}c = {'z': 5, 'w': 6}d = {'m': 7, 'h': 8, 'k': 9}e = ChainMap(a, b, c, d)print(e['a'], e['y'], e['z'], e['k'])

运行效果如下图所示:

ChainMap对象支持字典对象的所有方法,你可以完全像操作字典一样操作它。但是它不会真的把字典合并在一起,而是在内部储存一个Key到每个字典的映射,当你读取 e[key]的时候,它先去查询这个key在哪个字典里面,然后再去对应的字典里面查询对应的值。所以使用ChainMap几乎不需要额外的内存空间(当然这个对象自己会占用一些空间,但是如果要合并大字典,那么它自己占用的空间几乎可以忽略)。

所以你是不是觉得使用 ChainMap就能实现完美合并字典了呢?

在使用它之前,你一定要理解它的运行原理。如果你理解了它的运行原理,那么下面几个问题,你在运行代码之前就会知道结果是什么:

  1. 如果两个字典里面有一个Key的名字相同,那么使用ChainMap以后会读取哪一个?
  2. 如果为ChainMap对象添加一个Key-Value对,那么这个值会添加到哪里?
  3. 如果从原字典里面删除一个Key,ChainMap对象里面的Key也会消失吗?
  4. 如果从ChainMap对象里面删除一个Key,那么原字典里面的Key会消失吗?

首先来说第一个问题的答案:

ChainMap对象会使用第一个拥有这个Key的字典里面的值,如下图所示:

第二个问题,新的Key-Value会被添加进第一个字典里面,如下图所示:

第三个问题,如果修改了原来的字典,那么 ChainMap对象也会相应更新:

第四个问题,如果这个Key只在一个源字典中存在,那么这个Key会被从源字典中删除。如果这个Key在多个字典中都存在,那么Key会被从第一个字典中删除。当被从第一个字典中删除以后,第二个源字典的Key可以继续被 ChainMap读取。

以上4点,在你使用 ChainMap的时候一定要牢记,否则可能会导致你发现不了的Bug。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档