# 假如又两个字典: a = {"x":1, "z":3} b = {"y":2, "z":4} # 怎么将这两个字典映射到一个新字典里呢?愚蠢的办法是使用字典合并 # 这个方法会把右边的b刷写到a里 c = a|b print(c) # 但是,你会发现,如果原字典被改了,那c不会有变化: a["x"] = 2 print(c) # 这个时候使用映射方案的chainmap就会很好用 from collections import ChainMap c = ChainMap(a,b) print(",".join(str(x) for x in [c['x'], c['y'], c['z']])) print(len(c)) # 如果此时更改原字典的值: a["x"] = 1 # 输出也跟着更改了 print(",".join(str(x) for x in [c['x'], c['y'], c['z']])) print(len(c)) # 注,chainmap中如果有重复的键,则会采用左值,比如上面的例子使用a["z"]作为重复键z的取值; # 如果修改字典值,也会作用在左值上 del c["z"] print(",".join(str(x) for x in [c['x'], c['y'], c['z']])) print(a, b) # 如果尝试删除a里已经没有但b里有的键,那么会报错 try: del c["z"] except: print("在a里没找到键") # 这东西的底层其实是一个链表,演示如下: dic = ChainMap() dic["x"] = 1 dic = dic.new_child() print(dic) dic["x"] = 2 dic = dic.new_child() print(dic) dic["x"] = 3 print(dic) # 从这里我们开始回溯历史 dic = dic.parents print(dic) dic = dic.parents print(dic) dic = dic.parents print(dic) # 可以看到我们用new_child()函数创建了一个新节点;用parents属性来回溯