朝鲜世界杯_2019篮球世界杯 - dyldrk.com

Python dict: 深度字典更新, 比update更好用

在进行字典更新时, 我们通常都是用update函数, 但这个函数只能更新第一层, 如果第2/3/...层也需要更新的, 就不能再用update了, 否则从第2层起都会被覆盖;

由于暂时没有找到合适的方法, 就自己写了一个函数, 来进行字典的深度更新, 可以代替update, 能够满足浅层和深层的更新.

1. 问题描述

先定义两个字典:

dict_1 = {"A": 1, "B": {"b1": 1, "b2": 2}}

dict_2 = {"B": {"b2": 22, "b3": 3, "b4": {"bb1": 1}}, "C": 3}

我们想要达到的目的是: 使用dict_2来更新dict_1, 将dict_2中有而dict_1没有的key更新到dict_1, 同时将其共有的key更新为dict_2中的内容;

按照这个要求, 我们期望的结果应该是:

{'A': 1, 'B': {'b1': 1, 'b2': 22, 'b3': 3, 'b4': {'bb1': 1}}, 'C': 3}

如果我们直接用自带的update来更新, 效果是这样的:

dict_1.update(dict_2)

print(dict_1)

# result: {'A': 1, 'B': {'b2': 22, 'b3': 3, 'b4': {'bb1': 1}}, 'C': 3}

可见, update会直接把第一层的value直接覆盖过去, 对于dict_1['B']直接替换为了dict_2['B'], 导致dict_1['B']['b1']丢失; 这显然不是我们想要的结果.

2. 解决方案

解决的思路很简单, 分两步:

对于原dict有而新dict没有的key, 递归进行赋值;

对于新dict有而原dict没有的key, 添加到原dict中;

代码实现如下:

def dict_update(raw, new):

dict_update_iter(raw, new)

dict_add(raw, new)

def dict_update_iter(raw, new):

for key in raw:

if key not in new.keys():

continue

if isinstance(raw[key], dict) and isinstance(new[key], dict):

dict_update(raw[key], new[key])

else:

raw[key] = new[key]

def dict_add(raw, new):

update_dict = {}

for key in new:

if key not in raw.keys():

update_dict[key] = new[key]

raw.update(update_dict)

if __name__ == '__main__':

dict_1 = {"A": 1, "B": {"b1": 1, "b2": 2}}

dict_2 = {"B": {"b2": 22, "b3": 3, "b4": {"bb1": 1}}, "C": 3}

# dict_1.update(dict_2)

dict_update(dict_1, dict_2)

print(dict_1)

使用了dict_update函数, dict_1的内容就成了:

{'A': 1, 'B': {'b1': 1, 'b2': 22, 'b3': 3, 'b4': {'bb1': 1}}, 'C': 3}

目标达成!