在Python中合并字典模块ChainMap的隐藏坑【推荐】

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

a = {'a': 1, 'b': 2}
b = {'x': 3, 'y': 4}
a.update(b)
print(a)

运行效果如下图所示:

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

a = {'a': 1, 'b': 2}
b = {'x': 3, 'y': 4}
c = dict(a)
c.update(b)
print(c)
print(a)

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

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

答案就是 collections 模块下面的 ChainMap

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

例如:

from collections import ChainMap
a = {'a': 1, 'b': 2}
b = {'x': 3, 'y': 4}
c = ChainMap(a, b)
print(c['a'])
print(c['y'])

运行效果如下图所示:

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

from collections import ChainMap
a = {'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 就能实现完美合并字典了呢?

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

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

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

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

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

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

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

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

总结

以上所述是小编给大家介绍的在Python中合并字典模块ChainMap的隐藏坑,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

(0)

相关推荐

  • Python实现合并字典的方法

    本文实例讲述了Python实现合并字典的方法.分享给大家供大家参考.具体实现方法如下: # 将两个字典合并 #!/usr/bin/python def adddict(dict1,dict2): xin = {} for key in dict1.keys(): xin[key] = dict1[key] for key in dict2.keys(): xin[key] = dict2[key] return xin s1 = {1:222,'c':'d','e':'f'} s2 = {2:3

  • Python编写合并字典并实现敏感目录的小脚本

    0x00 起因 接触网安快一年了,爱收集一些字典啊敏感目录文件啊什么的.收集多了难免有重复,并且有的也需要合并使用方便.自己就写了一个小小的脚步用来完成这个目的. 0x01 代码 第一次发表文章,希望大家多提意见.抱拳了! 代码我就贴出来了 import osimport time import argparse import optparse def Time(n,p): pat_time = p-n minute = pat_time/60 hour = minute/60 print(in

  • Python合并字典键值并去除重复元素的实例

    假设在python中有一字典如下: x={'a':'1,2,3', 'b':'2,3,4'} 需要合并为: x={'c':'1,2,3,4'} 需要做到三件事: 1. 将字符串转化为数值列表 2. 合并两个列表并添加新的键值 3. 去除重复元素 第1步通过常用的函数eval()就可以做到了,第2步需要添加一个键值并添加元素,第3步利用set集合的性质可以达到去重的效果,不过最后需要再将set集合转化为list列表.代码如下: x={'a':'1,2,3','b':'2,3,4'} x['c']=

  • python ChainMap 合并字典的实现步骤

    字典是Python语言中唯一的映射类型. 映射类型对象里哈希值(键,key)和指向的对象(值,value)是一对多的的关系,通常被认为是可变的哈希表. 字典对象是可变的,它是一个容器类型,能存储任意个数的Python对象,其中也可包括其他容器类型. 字典类型与序列类型的区别: 1. 存取和访问数据的方式不同. 2. 序列类型只用数字类型的键(从序列的开始按数值顺序索引): 3. 映射类型可以用其他对象类型作键(如:数字.字符串.元祖,一般用字符串作键),和序列类型的键不同,映射类型的键直4.接或

  • python ChainMap的使用和说明详解

    ChainMap是Python collections模块中的一个成员,它用来将多个map组合到一起.Chain是链条的意思,字面意思就是把map串联到一起. 问题的背景是我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步.如果想建立一个同步的查询方法,可以使用ChainMap 先看一下初步使用 from collections import ChainMap a = {"x&

  • 在Python中合并字典模块ChainMap的隐藏坑【推荐】

    在Python中,当我们有两个字典需要合并的时候,可以使用字典的 update 方法,例如: a = {'a': 1, 'b': 2} b = {'x': 3, 'y': 4} a.update(b) print(a) 运行效果如下图所示: 然而,这个方法有一个问题--它会改变其中一个字典.如果我们不想改变原有的两个字典,那么我们必需要单独再创建一个字典: a = {'a': 1, 'b': 2} b = {'x': 3, 'y': 4} c = dict(a) c.update(b) prin

  • Python中创建字典的几种方法总结(推荐)

    1.传统的文字表达式: >>> d={'name':'Allen','age':21,'gender':'male'} >>> d {'age': 21, 'name': 'Allen', 'gender': 'male'} 如果你可以事先拼出整个字典,这种方式是很方便的. 2.动态分配键值: >>> d={} >>> d['name']='Allen' >>> d['age']=21 >>> d[

  • Python中的字典合并与列表合并技巧

    目录 前言 1 合并字典 2 合并列表 前言 又到了每日分享Python小技巧的时候了,今天给大家分享的是Python中两种常见的数据类型合并方法. 1 合并字典 在某些场景下,我们需要对两个(多个)字典进行合并.例如需要将如下两个字典进行合并: dict1 = {"a": 2, "b": 3, "c": 5} dict2 = {"a": 1, "c": 3, "d": 8} 且合并后的

  • Python 中的 Counter 模块及使用详解(搞定重复计数)

    文章目录 参考描述Counter 模块Counter() 类Counter() 对象字典有序性KeyError魔术方法 \_\_missing\_\_ update() 方法 Counter 对象的常用方法most_common()elements()total()subtract() Counter 对象间的运算加法运算减法运算并集运算交集运算单目运算 Counter 对象间的比较>== 参考 项目 描述 Python 标准库 DougHellmann 著 / 刘炽 等 译 搜索引擎 Bing

  • Python中使用select模块实现非阻塞的IO

    Socket的英文原义是"孔"或"插座".作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务.Socket正如其英文原意那样,像一个多孔插座.一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110

  • 详解python中的hashlib模块的使用

    hashlib hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法 hashlib模块 #哈希算法也叫摘要算法,相同的数据始终得到相同的输出,不同的数据得到不同的输出. #(1)哈希将不可变的任意长度的数据,变成具有固定长度的唯一值 #(2)字典的键值对映射关系是通过哈希计算的,哈希存储的数据是散列(无序) # 应用场景:在需要效验功能时使用  用户密码的 => 加密,解密  相关效验的

  • 对python中使用requests模块参数编码的不同处理方法

    python中使用requests模块http请求时,发现中文参数不会自动的URL编码,并且没有找到类似urllib (python3)模块中urllib.parse.quote("中文")手动URL编码的方法.研究了半天发现requests模块对中文参数有3种不同的处理方式. 一.requests模块自动URL编码参数 要使参数自动URL编码,需要将请求参数以字典的形式定义,如下demo: import requests proxy = {"http":"

  • Python中内建模块collections如何使用

    collections是Python内建的一个集合模块,提供了许多有用的集合类. 这里举几个例子: namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: >>> p = (1, 2) 但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的. 定义一个class又小题大做了,这时,namedtuple就派上了用场: >>> from collections import namedtuple >>>

  • Python中logger日志模块详解

    1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息: print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据:logging则可以由开发者决定将信息输出到什么地方,以及怎么输出: Logger从来不直接实例化,经常通过logging模块级方法(Modu

  • 在Python中实现字典反转案例

    有时候会碰到需求,将字典来反转,即:字典中的键作为值,而字典中的值作为键.对于字典比较小,可以使用普通方法 方法一: 使用普通方法转换 >>> d = {'a': 1, 'b': 2, 'c': 3} >>> def invert_dict(d): ... return dict([(v,k) for (k,v) in d.iteritems()]) ... >>> invert_dict(d) {1: 'a', 2: 'b', 3: 'c'} 方法二

随机推荐