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})
相关推荐
尘浮生8 分钟前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
MessiGo8 分钟前
Python 爬虫 (1)基础 | 基础操作
开发语言·python
偶尔。5359 分钟前
什么是事务?事务有哪些特性?
数据库·oracle
安迁岚11 分钟前
【SQL Server】华中农业大学空间数据库实验报告 实验六 视图
数据库·sql·mysql·oracle·实验报告
小白不太白95012 分钟前
设计模式之 模板方法模式
java·设计模式·模板方法模式
Tech Synapse14 分钟前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
xoxo-Rachel20 分钟前
(超级详细!!!)解决“com.mysql.jdbc.Driver is deprecated”警告:详解与优化
java·数据库·mysql
乌啼霜满天24922 分钟前
JDBC编程---Java
java·开发语言·sql
肥猪猪爸32 分钟前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet