python collections 中的 ChainMap 类

ChainMap

chainMap 属于Python collections 模块下的一个子类,作用是将多个字典,组织成一个字典。当查询时,会按照构造时传入的字典的顺序进行查询。它比使用这些字典创建一个新字典要快。

简单示例

python 复制代码
# 导入ChainMap模块
from collections import ChainMap
h1 = {"a": 1, "b": 2, "c": 3}
h2 = {"a": 10, "b": 20, "d": 30}
# 将h1, h2组织成一个字典
h = ChainMap(h1, h2)
# 在第一个字典中查到了"a"这个key,返回该key对应的value
print(h["a"])
# 1
# 在第一个字典中没有查到了"a"这个key,然后在第二个字典的中查到了这个key,返回该key对应的value
print(h["d"])
#30

什么时候使用呢?

在Python中,配置文件通常是字典,系统配置和个人私有配置同时存在时候,可以使用ChainMap来构造出最终配置文件,构造时候个人私有配置在前,系统配置在后。这样,在使用的时候,个人配置就能覆盖系统配置。

常用操作

  • 初始化:chain_map = ChainMap(*maps)

    传入若干个字典,用来初始化。例如:chain_map = ChainMap(h1, h2)。这样就将多个字典组合在一起了。如果在初始化的时候,没有传入字典参数,则默认传入一个空字典。底层是将传入字典的引用保存在一个列表中。

  • 查询:查询时,依次查询每个字典,直到一个键被找到,并返回该值。

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    # 搜索操作会依次对字典进行搜索,返回第一个值
    print(h["a"])
    # 1
    print(h["d"])
    #30

    这样的目的是,让后面字典保持不变。例如第一个字典是私人配置,第二个字典是系统配置,操作只会影响个人配置,不会影响系统配置,这对于系统配置来说,是很重要的。

  • 新增:新增键值对只操作第一个字典。

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    # 新增操作只会对第一个字典进行操作,因为保存的是引用,因此,本质上是原字典执行的新增操作
    h["x"] = 10000
    print(h)# 只对第一个字典进行新增
    # ChainMap({'a': 1, 'b': 2, 'c': 3, 'x': 10000}, {'a': 10, 'b': 20, 'd': 30})
    print(h1)
    # {'a': 1, 'b': 2, 'c': 3, 'x': 10000}

    这样的目的是,让后面字典保持不变。例如第一个字典是私人配置,第二个字典是系统配置,操作只会影响个人配置,不会影响系统配置,这对于系统配置来说,是很重要的。

  • 更新:更新键值对只会操作第一个字典。

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    # 更新操作只会对第一个字典进行操作,因为保存的是引用,因此,本质上是原字典执行的更新操作
    h["a"] = 99
    print(h)
    # ChainMap({'a': 99, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'd': 30})
    print(h1)
    # {'a': 99, 'b': 2, 'c': 3}

    这样的目的是,让后面字典保持不变。例如第一个字典是私人配置,第二个字典是系统配置,操作只会影响个人配置,不会影响系统配置,这对于系统配置来说,是很重要的。

  • 删除:删除键值对只会操作第一个字典。如果操作失败,会抛出异常。

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    # 删除操作只会对第一个字典进行操作,因为保存的是引用,因此,本质上是原字典执行的删除操作
    del h["a"]
    print(h)
    # ChainMap({'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'd': 30})
    print(h1)
    # {'b': 2, 'c': 3}
    del h["a"]
    # 抛出异常,因为只会对第一个字典进行操作,在一个字典中删除不存在的key抛出异常。(不会对后续字典进行操作)

    这样的目的是,让后面字典保持不变。例如第一个字典是私人配置,第二个字典是系统配置,操作只会影响个人配置,不会影响系统配置,这对于系统配置来说,是很重要的。

其他属性与操作

  • maps 属性:底层保存各个字典的列表。可以直接对该属性进行操作,实质是对原字典进行操作

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    print(h.maps)
    # [{'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'd': 30}]
    # 使用该属性更改字典
    h.maps[0]["a"] = 123
    # 本质是改变原字典
    print(h1)
    # {'a': 123, 'b': 2, 'c': 3}     
  • new_child(m=None, **kwargs)方法:返回一个新的 ChainMap,字典m 位于第一位,其他位于后面,保存的是引用。如果没有指定m,相当于传入了一个空字典。调用 d.new_child() 等价于 ChainMap({}, *d.maps)。如果指定了任何关键字参数kwargs,它会更新所传入的字典。

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    # 传入的字典位于最前,传入的kwargs更新传入的字典
    hh = h.new_child({"a":-1}, b=10)
    # ChainMap({'a': -1, 'b': 10}, {'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'd': 30})
    print(hh)
  • parents属性:返回一个新的 ChainMap 对象,该对象等价于原对象去除了第一个字典。一个 d.parents 等价于 ChainMap(*d.maps[1:])

    python 复制代码
    from collections import ChainMap
    h1 = {"a": 1, "b": 2, "c": 3}
    h2 = {"a": 10, "b": 20, "d": 30}
    h = ChainMap(h1, h2)
    hh = h.parents
    print(hh)
    # ChainMap({'a': 10, 'b': 20, 'd': 30})
相关推荐
qh0526wy2 分钟前
pyqt5冻结+分页表
开发语言·python·qt
小小药6 分钟前
009-spring-bean的实例化流程
java·数据库·spring
井底哇哇9 分钟前
Apline linux 安装scikit-learn 过程记录
python·机器学习·scikit-learn
DashVector29 分钟前
如何通过HTTP API插入或更新Doc
大数据·数据库·数据仓库·人工智能·http·数据库架构·向量检索
海棠AI实验室31 分钟前
机器学习基础算法 (二)-逻辑回归
人工智能·python·机器学习
hac132232 分钟前
瀚高数据库
数据库
罗政33 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第12章 结束
java·开发语言·pdf
GraduationDesign38 分钟前
基于SpringBoot的蜗牛兼职网的设计与实现
java·spring boot·后端
今天不学习明天变拉吉1 小时前
大批量数据导入接口的优化
java·excel
小手cool1 小时前
取多个集合的交集
java