新聞中心
前言
集合是專門的容器數(shù)據(jù)類型(Container Datatype),可以替代Python的通用內(nèi)置容器,如dict、list、set和tuple。容器是一種特殊用途的對象,可用于存儲不同的對象。它提供了一種訪問所包含對象并遍歷它們的方法。

Python提供了實現(xiàn)容器數(shù)據(jù)類型的collections模塊。在章節(jié)系列中,我們將學習集合模塊中的不同類型集合融洽,其中包括:
- ChainMap
- Counter
- Deque
- DefaultDict
- NamedTuple
- OrderedDict
- UserDict
- UserList
- UserString
下面就來分別介紹這些容器類型——鏈式映射(ChainMap)。
認識ChainMap
Python的所提供的ChainMap類(就稱為鏈映射類),是個類似字典(dict)的類,用于快速鏈接許多個映射,以便將它們作為單個單元處理。它通常比創(chuàng)建一個新字典并運行多個update()調(diào)用要快得多。
其語法格式如下:
xchainMap = collections.ChainMap(*maps)
說明:語法格式中的collections是導入的完成模塊名稱。如果這樣導入該模塊:import collections as cts,則語法可變?yōu)椋篶lass cts.ChainMap(*maps),或則模糊導入:from collections import ChainMap,這樣可以修改為:ChainMap(*maps)。
ChainMap可將多個字典或其他映射組合在一起,創(chuàng)建一個單一的、可更新的視圖(字典列表)。如果沒有指定映射,則提供一個空字典,以便新的鏈式映射(ChainMap)總是至少有一個映射可以。
鏈映射的底層映射存儲在一個列表中。該列表是公共的,可以使用maps屬性來訪問或更新。除了maps屬性,鏈映射沒有其他的新擴展狀態(tài)。
ChainMap是通過引用來合并底層映射的。因此,如果其中一個底層映射得到更新,這些更改也將反映在ChainMap中。
鏈映射支持所有常用的字典(dict)方法。此外,還有一個maps屬性,用于創(chuàng)建新子上下文的方法,并且除了第一個映射,屬性maps可用于訪問所有映射——maps是個列表。
對應一個用戶可更新的映射列表,該列表從第一次搜索到最后一次搜索是有序的。它是唯一存儲的狀態(tài),可以通過修改來更改要搜索的映射。這樣的列表應該始終至少包含一個映射。
來看下面的簡單示例,代碼清單如下:
運行程序輸出結(jié)果如下:
ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'})
[{'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'}]上述清單中,我們用兩個字典定義一個ChainMap對象(chain_map)。然后我們打印輸出ChainMap對象和maps屬性。正如在輸出中看到的,結(jié)果是這些字典的構(gòu)成視圖。
訪問ChainMap的鍵值
我們可以通過使用keys()和values()方法來訪問ChainMap的鍵和值。代碼示例如下:
上述代碼輸出結(jié)果為:
KeysView(ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'}))
ValuesView(ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'}))如程序輸出結(jié)果所示,chain_map.keys()的結(jié)果是一個KeysView(鍵視圖),chain_map.values()的結(jié)果是一個ValuesView(值視圖)。這兩個視圖類型內(nèi)置類,都是可迭代對象,可以分別遍歷相應的鍵名和值對象。例如:
輸出結(jié)果為:
key = a,value=A
key = b,value=B
key = one,value=1
key = two,value=2
鏈映射包含的值為:
A;B;1;2;
結(jié)合代碼和輸出結(jié)果,很容易理解,即鏈式映射就是把多個映射(map有很多實現(xiàn),字典是其中的一種)打包成一個映射即鏈式映射,然后可以像操作字典樣操作訪問。比如像字典一樣這樣來訪問某個鍵的值:
print(chain_map['b'] )
也就是通過使用鍵名:chain_map[' one ']來訪問ChainMap底層字典中單個項的值。
為ChainMap添加新映射
ChainMap可以包含任意數(shù)量的字典。我們使用內(nèi)置的new_child()方法向ChainMap添加新字典。new_child()方法返回一個新的ChainMap,其中包含著新映射,后跟當前實例中的所有映射。這里需要注意的一點是,新添加的字典將放在ChainMap的開頭。來看示例:
運行程序,輸入結(jié)果如下:
Old: ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'})
New: ChainMap({'x': 0, 'y': 1}, {'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'})這里需要注意的是,用鏈式映射的new_child()方法添加新字典后,不改變原來的鏈映射,會返回一個新的ChainMap對象。另外,如果你修改鏈式映射所包含的映射或字典,變化也將體現(xiàn)在鏈式映射對象中。
另外,實踐中要當心:如果你按照字典操作來添加新的鍵值對,則該鍵值對會添加到鏈式映射所包含的第一個映射中,如:new_chain_map['X'] = 'Unkown' 。自己動手試試看。
所含映射有相同鍵怎么辦?
底層上,鏈式映射主要是為把多個字典或映射打包成一個映射,以便集中操作。如果所辦函的字典中有相同的鍵會怎樣呢?來看示例:
運行程序輸出結(jié)果如下:
ChainMap({'id': 21001, 'country': '大秦', 'emperor': '嬴政'}, {'name': '李靖', 'country': '大唐', 'title': '元帥'})
大秦
('name', '李靖')
('country', '大秦')
('title', '元帥')
('id', 21001)
('emperor', '嬴政')很顯然,鏈接的映射中出現(xiàn)相同字典項時,只讀取第一個,以第一個為準,而且當你更新一個鍵的值時,它也只是更新第一個映射內(nèi)容的鍵值。
如果你想一次更新所有映射中的相同鍵的值怎么辦呢?你可以自定義一個ChainMap子類來實現(xiàn),或定義更新方法。因為ChainMap中有個屬性maps持有完整的各個映射,可以基于此屬性來完成相同鍵的一次性更新。這里簡單給個通過方法的方式實現(xiàn)多映射相同鍵的一次更新。示例代碼如下:
當然,你可以寫得更復雜一點,以完成更多的需要,也可實現(xiàn)一次多個映射中的相同鍵的值。自己動手試試吧。
本文小結(jié)
本文主要介紹了Python集合模塊中的鏈式映射容器——ChainMap的使用,可以把多個字典打包成一個對象來操作。同時需要注意的是,該映射只是對原字典的引用,當你修改原字典時,相應的變化也為體現(xiàn)在鏈式映射中。同時,在為ChainMap新增新的鍵值對時,它會添加到所包含的第一個映射對象中。
當前名稱:Python編程:換種方式用字典之鏈式映射(ChainMap),盤它!
網(wǎng)站網(wǎng)址:http://m.fisionsoft.com.cn/article/dhgcdhe.html


咨詢
建站咨詢
