python的Chainmap函数使用介绍
我们有多个字典,想把它们合并成为一个单独的字典,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以至于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用ChainMap。
python内置函数ChainMap可以将多个字典合并为一个独有的字典,这样的操作 并不是对源数据的拷贝,而是指向源数据,假如原字典数据修改,ChainMap映射也会改变;如果对ChainMap的结果修改,那么原数据一样也会被修改,这样就不会造成数据不同步的问题,当然需要因使用场景而定。
一.ChainMap合并多个字典
使用ChainMap可以将多个字典串联起来,当做一个字典来处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解忧 @Blog(个人博客地址): shuopython.com @WeChat Official Account(微信公众号):猿说python @Github:www.github.com @File:python_chainmap.py @Time:2019/11/20 21:25 @Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累! """ from collections import ChainMap dict1= {"a":"zhangsan","b":"lisi"} dict2= {"c":"wangwu"} dict3= {"d":"liqui","e":"laowang"} new_dict = ChainMap(dict1,dict2,dict3) print(new_dict) print(type(new_dict)) ------------------------------------------------------------------------------------------ 输出结果: ChainMap({'a': 'zhangsan', 'b': 'lisi'}, {'c': 'wangwu'}, {'d': 'liqui', 'e': 'laowang'}) <class 'collections.ChainMap'> |
二.ChainMap查询和遍历
ChainMap函数将多个字典合并为一个字典,查询和遍历的方式和对普通字典的操作方式一样,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from collections import ChainMap dict1= {"a":"zhangsan","b":"lisi"} dict2= {"c":"wangwu"} dict3= {"d":"liqui","b":"laowang"} new_dict = ChainMap(dict1,dict2,dict3) # 查询,可以直接根据key值查新,和字典操作方式一样 print(new_dict["a"]) print(new_dict["b"]) #当多个字典中有相同的key值是,默认取第一个key对应的value print(new_dict["c"]) print("***"*20) # 遍历,可以直接根据key或者value遍历,和普通字典一样操作 for key,value in new_dict.items(): print(key,":",value) |
输出结果:
1 2 3 4 5 6 7 8 9 | zhangsan lisi wangwu ************************************************************ e : laowang c : wangwu d : liqui a : zhangsan b : lisi |
注意:如果在使用ChainMap合并多个字典时,字典中有重复的key值,默认取第一个字典中key对用的value,从原理上面讲,ChainMap实际上是把放入的字典存储在一个队列中,当进行字典的增加删除等操作只会在第一个字典上进行,当进行查找的时候会依次查找!
三.ChainMap修改
maps 方法会将串联起来的字典以列表的形式展示,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from collections import ChainMap dict1= {"a":"zhangsan","b":"lisi"} dict2= {"c":"wangwu"} dict3= {"d":"liqui","b":"laowang"} new_dict = ChainMap(dict1,dict2,dict3) print("new_dict修改数据之后:",new_dict) print("dict1修改数据之前:",dict1) # 操作列表中索引值为0的字典,修改key="a"对应的value new_dict.maps[0]["a"]=18 print("new_dict修改数据之后:",new_dict) print("dict1修改数据之后:",dict1) |
输出结果:
1 2 3 4 | new_dict修改数据之后: ChainMap({'a': 'zhangsan', 'b': 'lisi'}, {'c': 'wangwu'}, {'d': 'liqui', 'b': 'laowang'}) dict1修改数据之前: {'a': 'zhangsan', 'b': 'lisi'} new_dict修改数据之后: ChainMap({'a': 18, 'b': 'lisi'}, {'c': 'wangwu'}, {'d': 'liqui', 'b': 'laowang'}) dict1修改数据之后: {'a': 18, 'b': 'lisi'} |
注意:ChainMap使用就是原始字典,共用同一内存地址,因此原始数据修改,ChainMap映射也会改变;如果对ChainMap的结果修改,那么原数据一样也会被修改
四.ChainMap增加
可以通过new_child()函数添加一个新的空白字典,然后像普通字典一样操作添加数据,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from collections import ChainMap dict1= {"a":"zhangsan","b":"lisi"} dict2= {"c":"wangwu"} # 合并字典 new_dict = ChainMap(dict1,dict2) print(new_dict) # 添加数据 new_dict1 = new_dict.new_child() print(new_dict1) new_dict1["x"]=0 new_dict1["y"] = 100.0 print(new_dict1) |
输出结果:
1 2 3 | ChainMap({'a': 'zhangsan', 'b': 'lisi'}, {'c': 'wangwu'}) ChainMap({}, {'a': 'zhangsan', 'b': 'lisi'}, {'c': 'wangwu'}) ChainMap({'x': 0, 'y': 100.0}, {'a': 'zhangsan', 'b': 'lisi'}, {'c': 'wangwu'}) |
总结:
1、ChainMap可接受多个映射然后在逻辑上使它们表现为一个单独的映射结构;它只是维护了一个记录底层映射关系的列表,然后去重定义常用的字典操作;
2、如果有重复的键,会采用第一个映射中多对应的值;
3、修改ChainMap映射结构,会同时作用在自己和原始字典结构上;
4、可以使用字典的update()方法,来替代上面的合并方案;但是这就需要创建一个新的字典对象(或者修改原字典,破坏了原始数据),并且原始字典做了修改,并不会反映到新建的字典上;
5、ChainMap使用的就是原始字典,因此原字典变,它也会改变。