合併多個字典或映射
來自專欄 python進階學習+odoo項目實戰
假如你有如下兩個字典:
a = {x: 1, z: 3 }
b = {y: 2, z: 4 }
現在假設你必須在兩個字典中執行查找操作(比如先從a 中找,如果找不到再在b
中找)。一個非常簡單的解決方案就是使用collections 模塊中的ChainMap 類。比如:
from collections import ChainMap
c = ChainMap(a,b)
print(c[x]) # Outputs 1 (from a)
print(c[y]) # Outputs 2 (from b)
print(c[z]) # Outputs 3 (from a)
討論
一個ChainMap 接受多個字典並將它們在邏輯上變為一個字典。然後,這些字典並
不是真的合併在一起了,ChainMap 類只是在內部創建了一個容納這些字典的列表並重
新定義了一些常見的字典操作來遍歷這個列表。大部分字典操作都是可以正常使用的,
比如:
>>> len(c)
3
>>> list(c.keys())
[x, y, z]
>>> list(c.values())
[1, 2, 3]
>>>
如果出現重複鍵,那麼第一次出現的映射值會被返回。因此,例子程序中的c[z]
總是會返回字典a 中對應的值,而不是b 中對應的值。
對於字典的更新或刪除操作總是影響的是列表中第一個字典。比如:
>>> c[z] = 10
>>> c[w] = 40
>>> del c[x]
>>> a
{w: 40, z: 10}
>>> del c[y]
Traceback (most recent call last):
...
KeyError: "Key not found in the first mapping: y"
>>>
ChainMap 對於編程語言中的作用範圍變數(比如globals , locals 等)是非常有
用的。事實上,有一些方法可以使它變得簡單:
>>> values = ChainMap()
>>> values[x] = 1
>>> # Add a new mapping
>>> values = values.new_child()
>>> values[x] = 2
>>> # Add a new mapping
>>> values = values.new_child()
>>> values[x] = 3
>>> values
ChainMap({x: 3}, {x: 2}, {x: 1})
>>> values[x]
3
>>> # Discard last mapping
>>> values = values.parents
>>> values[x]
2
>>> # Discard last mapping
>>> values = values.parents
>>> values[x]
1
>>> values
ChainMap({x: 1})
>>>
作為ChainMap 的替代,你可能會考慮使用update() 方法將兩個字典合併。比如:
>>> a = {x: 1, z: 3 }
>>> b = {y: 2, z: 4 }
>>> merged = dict(b)
>>> merged.update(a)
>>> merged[x]
1
>>> merged[y]
2
>>> merged[z]
3
>>>
這樣也能行得通,但是它需要你創建一個完全不同的字典對象(或者是破壞現有
字典結構)。同時,如果原字典做了更新,這種改變不會反應到新的合併字典中去。比
如:
>>> a[x] = 13
>>> merged[x]
1
ChainMap 使用原來的字典,它自己不創建新的字典。所以它並不會產生上面所說
的結果,比如:
>>> a = {x: 1, z: 3 }
>>> b = {y: 2, z: 4 }
>>> merged = ChainMap(a, b)
>>> merged[x]
1
>>> a[x] = 42
>>> merged[x] # Notice change to merged dicts
42
>>>
推薦閱讀:
※小說《遇見番外篇》:Q賽數學討論班-劇本
※中國古代數學著作(一)
※最大根方法——一段往事
※如何培養孩子的數感?學霸教你以下幾招
TAG:數學 |