Data Structures and Built-ins

Why does merging dictionaries with ** store the most recent value for duplicated keys while using collections.ChainMap stores the first saved value for duplicated keys? (Focus on pepper being 0.4 in output of 1st example and 0.2 in 2nd example)

dict1 = {'pepper': 0.20, 'onion': 0.55}
dict2 = {'apple': 0.40, 'pepper': .25}
dict3 = {'pepper': 0.4, 'durian':1}

{**dict1,**dict2,**dict3}

Output: {‘pepper’: 0.4, ‘onion’: 0.55, ‘apple’: 0.4, ‘durian’: 1}

from collections import ChainMap

chained_dict = ChainMap(dict1,dict2,dict3)
{**chained_dict}

Output: {‘pepper’: 0.2, ‘durian’: 1, ‘apple’: 0.4, ‘onion’: 0.55}

Hey @hanqi,

Given your code:

from collections import ChainMap

dict1 = {'pepper': 0.20, 'onion': 0.55}
dict2 = {'apple': 0.40, 'pepper': .25}
dict3 = {'pepper': 0.4, 'durian':1}

Using ** operator
**kwargs is called keyword argument unpacking

x = {**dict1, **dict2, **dict3}

You can explicitly unpacked the arguments

x = {‘pepper’: 0.20, ‘onion’: 0.55, ‘apple’: 0.40,
‘pepper’: .25, ‘pepper’: 0.4, ‘durian’:1}

The values are updated by the last parameter. That is,

x[“pepper”] = 0.20
x[“pepper”] = 0.25
x[“pepper”] = 0.40

So, x[“pepper”] = 0.40

Hence the output:

Output: {‘pepper’: 0.4, ‘onion’: 0.55, ‘apple’: 0.4, ‘durian’: 1}

Using chainMap

x = chainMap(dict1, dict2,dict3)
Output: {‘pepper’: 0.2, ‘durian’: 1, ‘apple’: 0.4, ‘onion’: 0.55}

There’s a notion of priority of parameter.

  • dict1, dict2, and dict3 define parameter pepper. dict1's value for pepper will be used because dict1 has priority over dict2 and dict3 .
  • A := "dict1 has priority over dict2. That is, x[pepper]= 0.20 has priority over x[pepper]= 0.25"
  • B := "dict2 has priority over dict3. That is, x[pepper]= 0.25 has priority over x[pepper]= 0.40"
  • A and B => dict1 has priority over dict2 and dict3. Therefore x[pepper] = 0.20

To summarize:

  • ** keyword argument unpacking updates by last parameter
  • ChainMap updates by the order of priority first to last.

Hope it helps.

Best,
Alvin.

1 Like