Collections--ChainMap

  一個 ChainMap 類是爲了將多個映射快速的連接到一塊兒,這樣它們就能夠做爲一個單元處理。它一般比建立一個新字典和屢次調用 update() 要快不少。html

class collections.ChainMap(*maps)python

支持全部經常使用字典方法。另外還有一個 maps 屬性(attribute),一個建立子上下文的方法(method), 一個存取它們首個映射的屬性(property):app

maps

  一個能夠更新的映射列表。這個列表是按照第一次搜索到最後一次搜索的順序組織的。它是僅有的存儲狀態,能夠被修改。列表最少包含一個映射。spa

 

new_child(m=None)

  返回一個新的 ChainMap 類,包含了一個新映射(map),後面跟隨當前實例的所有映射(map)。若是 m 被指定,它就成爲不一樣新的實例,就是在全部映射前加上 m,若是沒有指定,就加上一個空字典,這樣的話一個 d.new_child() 調用等價於 ChainMap({}, *d.maps) 。這個方法用於建立子上下文,不改變任何父映射的值。命令行

在 3.4 版更改: 添加了 m 可選參數。code

 

parents

屬性返回一個新的 ChainMap 包含全部的當前實例的映射,除了第一個。這樣能夠在搜索的時候跳過第一個映射。htm

 

 

如今假設你必須在兩個字典中執行查找操做 (好比先從 a 中找,若是找不到再在 b中找)。一個很是簡單扼解決方案就是使用 collections 模塊中的 ChainMap 類。好比:
In [46]: a = {'x': 1, 'z': 3 }                                                                                                       

In [47]: b = {'y': 2, 'z': 4 }                                                                                                       

In [48]: from collections import ChainMap                                                                                            

In [49]: c=ChainMap(a,b)                                                                                                             

In [50]: c.get('x')                                                                                                                  
Out[50]: 1

In [51]: c.get('z')                                                                                                                  
Out[51]: 3

In [52]: c.get('y')                                                                                                                  
Out[52]: 2

  若是出現重複鍵,那麼第一次出現的映射值會被返回。所以,例子程序中的c['z']老是會返回字典a中對應的值,而不是b中對應的值。blog

 

對於字典的更新或刪除操做老是影響的是列表中第一個字典。好比:
In [65]: c                                                                                                                           
Out[65]: ChainMap({'x': 1, 'z': 10}, {'y': 2, 'z': 4})

In [66]: c['x']=10                                                                                                                   

In [67]: c['z']=10                                                                                                                   

In [68]: c                                                                                                                           
Out[68]: ChainMap({'x': 10, 'z': 10}, {'y': 2, 'z': 4})

del c['y']

KeyError: "Key not found in the first mapping: 'y'"

  

一個 ChainMap 經過引用合併底層映射。 因此,若是一個底層映射更新了,這些更改會反映到 ChainMap 。get

In [71]: a['x']=100                                                                                                                  

In [72]: c                                                                                                                           
Out[72]: ChainMap({'x': 100, 'z': 10}, {'y': 2, 'z': 4})

  

new_child()方法和parents屬性it

d=c.new_child()                                                                                                             

In [81]: d                                                                                                                           
Out[81]: ChainMap({}, {'x': 100, 'z': 10}, {'y': 2, 'z': 4})

In [82]: d['x']=1                                                                                                                    

In [83]: d                                                                                                                           
Out[83]: ChainMap({'x': 1}, {'x': 100, 'z': 10}, {'y': 2, 'z': 4})

In [84]: d=d.new_child()                                                                                                             

In [85]: d['x']=2                                                                                                                    

In [86]: d                                                                                                                           
Out[86]: ChainMap({'x': 2}, {'x': 1}, {'x': 100, 'z': 10}, {'y': 2, 'z': 4})

In [89]: d=d.parents                                                                                                                 

In [90]: d['x']                                                                                                                      
Out[90]: 1

In [91]: d                                                                                                                           
Out[91]: ChainMap({'x': 1}, {'x': 100, 'z': 10}, {'y': 2, 'z': 4})

In [92]: d=d.parents                                                                                                                 

In [93]: d['x']                                                                                                                      
Out[93]: 100

  

 

典型用例

讓用戶指定的命令行參數優先於環境變量,優先於默認值的例子

import os, argparse

defaults = {'color': 'red', 'user': 'guest'}

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = {k:v for k, v in vars(namespace).items() if v}

combined = ChainMap(command_line_args, os.environ, defaults)
print(combined['color'])
print(combined['user'])
本站公眾號
   歡迎關注本站公眾號,獲取更多信息