zoukankan      html  css  js  c++  java
  • python ChainMap的使用和说明

        问题的背景是我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用ChainMap

        先看一下初步使用

    from collections import ChainMap
    a = {"x":1, "z":3} b = {"y":2, "z":4} c = ChainMap(a,b) print(c) print("x: {}, y: {}, z: {}".format(c["x"], c["y"], c["z"])) 输出: ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}) x: 1, y: 2, z: 3 [Finished in 0.1s]

        这是ChainMap最基本的使用,可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。

        有一个注意点就是当对ChainMap进行修改的时候总是只会对第一个字典进行修改

    In [6]: a = {"x":1, "z":3}
    
    In [7]: b = {"y":2, "z":4}
    
    In [8]: c = ChainMap(a, b)
    
    In [9]: c
    Out[9]: ChainMap({'z': 3, 'x': 1}, {'z': 4, 'y': 2})
    
    In [10]: c["z"]
    Out[10]: 3
    
    In [11]: c["z"] = 4
    
    In [12]: c
    Out[12]: ChainMap({'z': 4, 'x': 1}, {'z': 4, 'y': 2})
    
    In [13]: c.pop('z')
    Out[13]: 4
    
    In [14]: c
    Out[14]: ChainMap({'x': 1}, {'z': 4, 'y': 2})
    
    In [15]: del c["y"]
    ---------------------------------------------------------------------------
    KeyError                                  Traceback (most recent call last)
    。。。。。。
    KeyError: "Key not found in the first mapping: 'y'"

      

      ChainMap和带有作用域的值,诸如全局变量,局部变量之间工作的时候特别有效,

    In [4]: a = ChainMap()
    
    In [5]: a["x"]=1
    
    In [6]: a
    Out[6]: ChainMap({'x': 1})
    
    In [7]: b = a.new_child()
    
    In [8]: b
    Out[8]: ChainMap({}, {'x': 1})
    
    In [9]: b["x"] = 2
    
    In [10]: b
    Out[10]: ChainMap({'x': 2}, {'x': 1})
    
    In [11]: b["y"] = 3
    
    In [12]: b
    Out[12]: ChainMap({'x': 2, 'y': 3}, {'x': 1})
    
    In [13]: a
    Out[13]: ChainMap({'x': 1})
    
    In [14]: c = a.new_child()
    
    In [15]: c
    Out[15]: ChainMap({}, {'x': 1})
    
    In [16]: c["x"]
    Out[16]: 1
    
    In [17]: c["y"] = 1
    
    In [18]: c
    Out[18]: ChainMap({'y': 1}, {'x': 1})
    
    In [19]: d = c.parents()
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-19-dc4debb7ca3b> in <module>()
    ----> 1 d = c.parents()
    
    TypeError: 'ChainMap' object is not callable
    
    In [20]: d = c.parents
    
    In [21]: d
    Out[21]: ChainMap({'x': 1})
    
    In [22]: d is a
    Out[22]: False
    
    In [23]: d == a
    Out[23]: True

    从原理上面讲,ChainMap实际上是把放入的字典存储在一个队列中,当进行字典的增加删除等操作只会在第一个字典上进行,当进行查找的时候会依次查找,new_child()方法实质上是在列表的第一个元素前放入一个字典,默认是{},而parents是去掉了列表开头的元素

    In [24]: a = {"x":1, "z":3}
    
    In [25]: b = {"y":2, "z":4}
    
    In [26]: c = ChainMap(a,b)
    
    In [27]: c
    Out[27]: ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
    
    In [28]: c.maps
    Out[28]: [{'x': 1, 'z': 3}, {'y': 2, 'z': 4}]
    
    In [29]: c.parents
    Out[29]: ChainMap({'y': 2, 'z': 4})
    
    In [30]: c.parents.maps
    Out[30]: [{'y': 2, 'z': 4}]
    
    In [31]: c.parents.parents
    Out[31]: ChainMap({})
    
    In [32]: c.parents.parents.parents
    Out[32]: ChainMap({})

    也正是因为底层是列表实现的,所以实际上ChainMap查询的字典实际上还是原来的字典的引用

    参考 python cookbook,

  • 相关阅读:
    被Play framework狠狠的play了一把
    ant导入Zookeeper到Eclipse错误path contains invalid character
    Hadoop2.4代码的坑
    uml类关系
    Hadoop 源码编译导出
    Eclipse 导入 Hadoop 源码
    js中的prototype和constructor
    react之路:使用redux-immutable
    react之路:使用actionCreators和constants
    react之路:使用combineReducers拆分reducer
  • 原文地址:https://www.cnblogs.com/mangmangbiluo/p/9882097.html
Copyright © 2011-2022 走看看