標籤:

合併多個字典或映射

合併多個字典或映射

來自專欄 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:數學 |