更新不同深度的嵌套字典的值
- 2025-01-03 08:41:00
- admin 原创
- 88
问题描述:
我正在寻找一种方法来dictionary1
用 dict 的内容更新 dictupdate
而不覆盖levelA
dictionary1 = {
"level1": {
"level2": {"levelA": 0, "levelB": 1}
}
}
update = {
"level1": {
"level2": {"levelB": 10}
}
}
dictionary1.update(update)
print(dictionary1)
{
"level1": {
"level2": {"levelB": 10}
}
}
我知道更新会删除 level2 中的值,因为它正在更新最低键 level1。
鉴于 dictionary1 和 update 可以有任意长度,我该如何解决这个问题?
解决方案 1:
@FM 的答案有正确的总体思路,即递归解决方案,但编码有些奇怪,并且至少有一个错误。我建议:
Python 2:
import collections
def update(d, u):
for k, v in u.iteritems():
if isinstance(v, collections.Mapping):
d[k] = update(d.get(k, {}), v)
else:
d[k] = v
return d
Python 3:
import collections.abc
def update(d, u):
for k, v in u.items():
if isinstance(v, collections.abc.Mapping):
d[k] = update(d.get(k, {}), v)
else:
d[k] = v
return d
当“更新”有一个项目时,就会出现错误k
,v
其中v
是dict
并且k
最初不是被更新字典中的键——@FM 的代码“跳过”了更新的这一部分(因为它在一个空的新值上执行它,这个新dict
值没有保存或返回到任何地方,只是在递归调用返回时丢失)。
if
我的其他更改很小:当/else
构造.get
可以更快、更干净地完成相同的工作时,没有理由这样做,并且isinstance
最好将其应用于抽象基类(而不是具体基类)以实现通用性。
解决方案 2:
如果你碰巧使用pydantic(顺便说一下,这是一个很棒的库),那么你可以使用它的一个实用方法:
from pydantic.utils import deep_update
dictionary1 = deep_update(dictionary1, update)
更新:参考代码,正如@Jorgu指出的那样。如果不想安装 pydantic,代码很短,可以复制,只要有足够的许可证兼容性。
解决方案 3:
这道题花了我一点时间,但多亏了 @Alex 的帖子,他填补了我遗漏的空白。但是,我遇到了一个问题,如果递归中的值dict
恰好是list
,那么我会分享并扩展他的答案。
import collections
def update(orig_dict, new_dict):
for key, val in new_dict.iteritems():
if isinstance(val, collections.Mapping):
tmp = update(orig_dict.get(key, { }), val)
orig_dict[key] = tmp
elif isinstance(val, list):
orig_dict[key] = (orig_dict.get(key, []) + val)
else:
orig_dict[key] = new_dict[key]
return orig_dict
解决方案 4:
{}
与接受的解决方案相同,但变量命名、文档字符串更清晰,并修复了值不会覆盖的错误。
import collections
def deep_update(source, overrides):
"""
Update a nested dictionary or similar mapping.
Modify ``source`` in place.
"""
for key, value in overrides.iteritems():
if isinstance(value, collections.Mapping) and value:
returned = deep_update(source.get(key, {}), value)
source[key] = returned
else:
source[key] = overrides[key]
return source
以下是一些测试用例:
def test_deep_update():
source = {'hello1': 1}
overrides = {'hello2': 2}
deep_update(source, overrides)
assert source == {'hello1': 1, 'hello2': 2}
source = {'hello': 'to_override'}
overrides = {'hello': 'over'}
deep_update(source, overrides)
assert source == {'hello': 'over'}
source = {'hello': {'value': 'to_override', 'no_change': 1}}
overrides = {'hello': {'value': 'over'}}
deep_update(source, overrides)
assert source == {'hello': {'value': 'over', 'no_change': 1}}
source = {'hello': {'value': 'to_override', 'no_change': 1}}
overrides = {'hello': {'value': {}}}
deep_update(source, overrides)
assert source == {'hello': {'value': {}, 'no_change': 1}}
source = {'hello': {'value': {}, 'no_change': 1}}
overrides = {'hello': {'value': 2}}
deep_update(source, overrides)
assert source == {'hello': {'value': 2, 'no_change': 1}}
该函数可以在charlatan包中使用charlatan.utils
。
解决方案 5:
@Alex 的答案很好,但在用字典替换整数等元素时不起作用,例如update({'foo':0},{'foo':{'bar':1}})
。此更新解决了此问题:
import collections
def update(d, u):
for k, v in u.iteritems():
if isinstance(d, collections.Mapping):
if isinstance(v, collections.Mapping):
r = update(d.get(k, {}), v)
d[k] = r
else:
d[k] = u[k]
else:
d = {k: u[k]}
return d
update({'k1': 1}, {'k1': {'k2': {'k3': 3}}})
解决方案 6:
这是一个递归字典合并的不可变版本,以防有人需要它。
根据@Alex Martelli 的回答。
Python 3.x:
from collections.abc import Mapping
from copy import deepcopy
def merge(dict1, dict2):
''' Return a new dictionary by merging two dictionaries recursively. '''
result = deepcopy(dict1)
for key, value in dict2.items():
if isinstance(value, Mapping):
result[key] = merge(result.get(key, {}), value)
else:
result[key] = deepcopy(dict2[key])
return result
Python 2.x:
import collections
from copy import deepcopy
def merge(dict1, dict2):
''' Return a new dictionary by merging two dictionaries recursively. '''
result = deepcopy(dict1)
for key, value in dict2.iteritems():
if isinstance(value, collections.Mapping):
result[key] = merge(result.get(key, {}), value)
else:
result[key] = deepcopy(dict2[key])
return result
解决方案 7:
这个问题很老了,但我在寻找“深度合并”解决方案时遇到了这个问题。上面的答案启发了我接下来的内容。我最终自己写了这个问题,因为我测试的所有版本都有错误。忽略的关键点是,在两个输入字典的某个任意深度,对于某个键 k,当 d[k] 或 u[k] 不是字典时,决策树是有缺陷的。
此外,该解决方案不需要递归,这与dict.update()
工作原理和返回更加对称None
。
import collections
def deep_merge(d, u):
"""Do a deep merge of one dict into another.
This will update d with values in u, but will not delete keys in d
not found in u at some arbitrary depth of d. That is, u is deeply
merged into d.
Args -
d, u: dicts
Note: this is destructive to d, but not u.
Returns: None
"""
stack = [(d,u)]
while stack:
d,u = stack.pop(0)
for k,v in u.items():
if not isinstance(v, collections.Mapping):
# u[k] is not a dict, nothing to merge, so just set it,
# regardless if d[k] *was* a dict
d[k] = v
else:
# note: u[k] is a dict
if k not in d:
# add new key into d
d[k] = v
elif not isinstance(d[k], collections.Mapping):
# d[k] is not a dict, so just set it to u[k],
# overriding whatever it was
d[k] = v
else:
# both d[k] and u[k] are dicts, push them on the stack
# to merge
stack.append((d[k], v))
解决方案 8:
只需使用python-benedict
(我做到了),它有一个merge
(deepupdate)实用方法和许多其他方法。它适用于 python 2 / python 3,并且经过了充分测试。
from benedict import benedict
dictionary1=benedict({'level1':{'level2':{'levelA':0,'levelB':1}}})
update={'level1':{'level2':{'levelB':10}}}
dictionary1.merge(update)
print(dictionary1)
# >> {'level1':{'level2':{'levelA':0,'levelB':10}}}
安装:pip install python-benedict
文档:https ://github.com/fabiocaccamo/python-benedict
注:我是这个项目的作者
解决方案 9:
对@Alex 的答案进行了细微改进,可以更新不同深度的字典,并限制更新深入原始嵌套字典的深度(但更新字典的深度不受限制)。仅测试了少数情况:
def update(d, u, depth=-1):
"""
Recursively merge or update dict-like objects.
>>> update({'k1': {'k2': 2}}, {'k1': {'k2': {'k3': 3}}, 'k4': 4})
{'k1': {'k2': {'k3': 3}}, 'k4': 4}
"""
for k, v in u.iteritems():
if isinstance(v, Mapping) and not depth == 0:
r = update(d.get(k, {}), v, depth=max(depth - 1, -1))
d[k] = r
elif isinstance(d, Mapping):
d[k] = u[k]
else:
d = {k: u[k]}
return d
解决方案 10:
下面的代码应该可以update({'k1': 1}, {'k1': {'k2': 2}})
正确解决@Alex Martelli 的答案中的问题。
def deepupdate(original, update):
"""Recursively update a dict.
Subdict's won't be overwritten but also updated.
"""
if not isinstance(original, abc.Mapping):
return update
for key, value in update.items():
if isinstance(value, abc.Mapping):
original[key] = deepupdate(original.get(key, {}), value)
else:
original[key] = value
return original
解决方案 11:
我使用了@Alex Martelli 建议的解决方案,但失败了
TypeError 'bool' object does not support item assignment
当两个字典的数据类型在某种程度上有所不同时。
如果在同一级别,字典的元素d
只是一个标量(即Bool
),而字典的元素u
仍然是字典,则重新分配会失败,因为无法将字典分配到标量(如True[k]
)。
一个附加条件修复了以下问题:
from collections import Mapping
def update_deep(d, u):
for k, v in u.items():
# this condition handles the problem
if not isinstance(d, Mapping):
d = u
elif isinstance(v, Mapping):
r = update_deep(d.get(k, {}), v)
d[k] = r
else:
d[k] = u[k]
return d
解决方案 12:
感谢hobs对Alex 的 回答的评论。确实update({'k1': 1}, {'k1': {'k2': 2}})
会导致TypeError: 'int' object does not support item assignment.
我们应该在函数开始时检查输入值的类型。因此,我建议使用以下函数,它应该可以解决此问题(以及其他问题)。
Python 3:
from collections.abc import Mapping
def deep_update(d1, d2):
if all((isinstance(d, Mapping) for d in (d1, d2))):
for k, v in d2.items():
d1[k] = deep_update(d1.get(k), v)
return d1
return d2
解决方案 13:
在这两个答案中,作者似乎都不理解更新存储在字典中的对象的概念,甚至不理解迭代字典项(而不是键)的概念。所以我不得不写一个不会进行毫无意义的重复字典存储和检索的答案。假设字典存储其他字典或简单类型。
def update_nested_dict(d, other):
for k, v in other.items():
if isinstance(v, collections.Mapping):
d_v = d.get(k)
if isinstance(d_v, collections.Mapping):
update_nested_dict(d_v, v)
else:
d[k] = v.copy()
else:
d[k] = v
或者更简单的适用于任何类型:
def update_nested_dict(d, other):
for k, v in other.items():
d_v = d.get(k)
if isinstance(v, collections.Mapping) and isinstance(d_v, collections.Mapping):
update_nested_dict(d_v, v)
else:
d[k] = deepcopy(v) # or d[k] = v if you know what you're doing
解决方案 14:
更新@Alex Martelli 的答案以修复其代码中的错误,从而使解决方案更加健壮:
def update_dict(d, u):
for k, v in u.items():
if isinstance(v, collections.Mapping):
default = v.copy()
default.clear()
r = update_dict(d.get(k, default), v)
d[k] = r
else:
d[k] = v
return d
关键是我们经常想在递归时创建相同的类型v.copy().clear()
,所以这里我们使用但不是。如果这里的类型可以有不同类型的s,{}
这尤其有用。dict
`collections.defaultdict`default_factory
还请注意,u.iteritems()
已更改u.items()
为Python3
。
解决方案 15:
def update(value, nvalue):
if not isinstance(value, dict) or not isinstance(nvalue, dict):
return nvalue
for k, v in nvalue.items():
value.setdefault(k, dict())
if isinstance(v, dict):
v = update(value[k], v)
value[k] = v
return value
使用dict
或collections.Mapping
解决方案 16:
我建议用 替换{}
,type(v)()
以便传播存储在 中u
但不存在于 中的任何 dict 子类的对象类型d
。例如,这将保留 collections.OrderedDict 等类型:
Python 2:
import collections
def update(d, u):
for k, v in u.iteritems():
if isinstance(v, collections.Mapping):
d[k] = update(d.get(k, type(v)()), v)
else:
d[k] = v
return d
Python 3:
import collections.abc
def update(d, u):
for k, v in u.items():
if isinstance(v, collections.abc.Mapping):
d[k] = update(d.get(k, type(v)()), v)
else:
d[k] = v
return d
解决方案 17:
您可能像今天一样偶然发现了一个非标准字典,它没有 iteritems 属性。在这种情况下,很容易将这种类型的字典解释为标准字典。例如:
Python 2.7:
import collections
def update(orig_dict, new_dict):
for key, val in dict(new_dict).iteritems():
if isinstance(val, collections.Mapping):
tmp = update(orig_dict.get(key, { }), val)
orig_dict[key] = tmp
elif isinstance(val, list):
orig_dict[key] = (orig_dict[key] + val)
else:
orig_dict[key] = new_dict[key]
return orig_dict
import multiprocessing
d=multiprocessing.Manager().dict({'sample':'data'})
u={'other': 1234}
x=update(d, u)
x.items()
Python 3.8:
def update(orig_dict, new_dict):
orig_dict=dict(orig_dict)
for key, val in dict(new_dict).items():
if isinstance(val, collections.abc.Mapping):
tmp = update(orig_dict.get(key, { }), val)
orig_dict[key] = tmp
elif isinstance(val, list):
orig_dict[key] = (orig_dict[key] + val)
else:
orig_dict[key] = new_dict[key]
return orig_dict
import collections
import multiprocessing
d=multiprocessing.Manager().dict({'sample':'data'})
u={'other': 1234, "deeper": {'very': 'deep'}}
x=update(d, u)
x.items()
解决方案 18:
我知道这个问题已经很老了,但我仍然发布我在更新嵌套字典时所做的事情。我们可以利用 python 中字典通过引用传递的事实,假设键的路径已知并且以点分隔。外汇,如果我们有一个名为 data 的字典:
{
"log_config_worker": {
"version": 1,
"root": {
"handlers": [
"queue"
],
"level": "DEBUG"
},
"disable_existing_loggers": true,
"handlers": {
"queue": {
"queue": null,
"class": "myclass1.QueueHandler"
}
}
},
"number_of_archived_logs": 15,
"log_max_size": "300M",
"cron_job_dir": "/etc/cron.hourly/",
"logs_dir": "/var/log/patternex/",
"log_rotate_dir": "/etc/logrotate.d/"
}
我们要更新队列类,键的路径将是-log_config_worker.handlers.queue.class
我们可以使用以下函数来更新该值:
def get_updated_dict(obj, path, value):
key_list = path.split(".")
for k in key_list[:-1]:
obj = obj[k]
obj[key_list[-1]] = value
get_updated_dict(data, "log_config_worker.handlers.queue.class", "myclass2.QueueHandler")
这将正确更新字典。
解决方案 19:
我制作了一个简单的函数,其中你提供键、新值和字典作为输入,然后它使用值递归更新它:
def update(key,value,dictionary):
if key in dictionary.keys():
dictionary[key] = value
return
dic_aux = []
for val_aux in dictionary.values():
if isinstance(val_aux,dict):
dic_aux.append(val_aux)
for i in dic_aux:
update(key,value,i)
for [key2,val_aux2] in dictionary.items():
if isinstance(val_aux2,dict):
dictionary[key2] = val_aux2
dictionary1={'level1':{'level2':{'levelA':0,'levelB':1}}}
update('levelB',10,dictionary1)
print(dictionary1)
#output: {'level1': {'level2': {'levelA': 0, 'levelB': 10}}}
希望它能解答。
解决方案 20:
是的!还有另一种解决方案。我的解决方案在检查的键上有所不同。在所有其他解决方案中,我们只查看 中的键dict_b
。但在这里,我们查看两个字典的并集。
随心所欲地处理
def update_nested(dict_a, dict_b):
set_keys = set(dict_a.keys()).union(set(dict_b.keys()))
for k in set_keys:
v = dict_a.get(k)
if isinstance(v, dict):
new_dict = dict_b.get(k, None)
if new_dict:
update_nested(v, new_dict)
else:
new_value = dict_b.get(k, None)
if new_value:
dict_a[k] = new_value
解决方案 21:
如果您想替换“带有数组的完整嵌套字典”,您可以使用以下代码片段:
它将用“new_value”替换任何“old_value”。它大致是对字典进行深度优先重建。它甚至可以使用作为第一级输入参数的 List 或 Str/int。
def update_values_dict(original_dict, future_dict, old_value, new_value):
# Recursively updates values of a nested dict by performing recursive calls
if isinstance(original_dict, Dict):
# It's a dict
tmp_dict = {}
for key, value in original_dict.items():
tmp_dict[key] = update_values_dict(value, future_dict, old_value, new_value)
return tmp_dict
elif isinstance(original_dict, List):
# It's a List
tmp_list = []
for i in original_dict:
tmp_list.append(update_values_dict(i, future_dict, old_value, new_value))
return tmp_list
else:
# It's not a dict, maybe a int, a string, etc.
return original_dict if original_dict != old_value else new_value
解决方案 22:
使用递归的另一种方法:
def updateDict(dict1,dict2):
keys1 = list(dict1.keys())
keys2= list(dict2.keys())
keys2 = [x for x in keys2 if x in keys1]
for x in keys2:
if (x in keys1) & (type(dict1[x]) is dict) & (type(dict2[x]) is dict):
updateDict(dict1[x],dict2[x])
else:
dict1.update({x:dict2[x]})
return(dict1)
解决方案 23:
感谢:@Gustavo Alves Casqueiro 的原始答案
说实话,我本来希望使用一个可以为我完成繁重工作的库,但我就是找不到可以满足我需求的东西。
我只是对这个函数添加了几个额外的检查。
lists
我已经包含了对内的检查dict
,并添加了一个嵌套名称的参数,以便在 OUTER 中可能有另一个同名的KEY时dict
正确更新嵌套的KEY。dict
`dict`
更新功能:
def update(dictionary: dict[str, any], key: str, value: any, nested_dict_name: str = None) -> dict[str, any]:
if not nested_dict_name: # if current (outermost) dict should be updated
if key in dictionary.keys(): # check if key exists in current dict
dictionary[key] = value
return dictionary
else: # if nested dict should be updated
if nested_dict_name in dictionary.keys(): # check if dict is in next layer
if isinstance(dictionary[nested_dict_name], dict):
if key in dictionary[nested_dict_name].keys(): # check if key exists in current dict
dictionary[nested_dict_name][key] = value
return dictionary
if isinstance(dictionary[nested_dict_name], list):
list_index = random.choice(range(len(dictionary[nested_dict_name]))) # pick a random dict from the list
if key in dictionary[nested_dict_name][list_index].keys(): # check if key exists in current dict
dictionary[nested_dict_name][list_index][key] = value
return dictionary
dic_aux = []
# this would only run IF the above if-statement was not able to identity and update a dict
for val_aux in dictionary.values():
if isinstance(val_aux, dict):
dic_aux.append(val_aux)
# call the update function again for recursion
for i in dic_aux:
return update(dictionary=i, key=key, value=value, nested_dict_name=nested_dict_name)
原文:
{
"level1": {
"level2": {
"myBool": "Original",
"myInt": "Original"
},
"myInt": "Original",
"myBool": "Original"
},
"myStr": "Original",
"level3": [
{
"myList": "Original",
"myInt": "Original",
"myBool": "Original"
}
],
"level4": [
{
"myList": "Original",
"myInt": "UPDATED",
"myBool": "Original"
}
],
"level5": {
"level6": {
"myBool": "Original",
"myInt": "Original"
},
"myInt": "Original",
"myBool": "Original"
}
}
更新数据(使用pytest
):
@pytest.fixture(params=[(None, 'myStr', 'UPDATED'),
('level1', 'myInt', 'UPDATED'),
('level2', 'myBool', 'UPDATED'),
('level3', 'myList', 'UPDATED'),
('level4', 'myInt', 'UPDATED'),
('level5', 'myBool', 'UPDATED')])
def sample_data(request):
return request.param
在这个较小的用例中,该'UPDATED'
参数没有意义(因为我可以对其进行硬编码),但为了在读取日志时简单起见,我不想看到多种数据类型,只是让它显示一个'UPDATED'
字符串。
测试:
@pytest.mark.usefixtures('sample_data')
def test_this(sample_data):
nested_dict, param, update_value = sample_data
if nested_dict is None:
print(f'
Dict Value: Level0
Param: {param}
Update Value: {update_value}')
else:
print(f'
Dict Value: {nested_dict}
Param: {param}
Update Value: {update_value}')
# initialise data dict
data_object = # insert data here (see example dict above)
# first print as is
print(f'
Original Dict:
{data_object}')
update(dictionary=data_object,
key=param,
value=update_value,
nested_dict_name=nested_dict)
# print updated
print(f'
Updated Dict:
{data_object}')
当你有这样的字典时,有一个警告:
{
"level1": {
"level2": {
"myBool": "Original"
},
"myBool": "Original"
},
"level3": {
"level2": {
"myBool": "Original"
},
"myInt": "Original"
}
}
其中level2
在level1
AND之下level3
。这需要使用list
或 以及 并传入外部AND 内部( )nested_dict_name
的名称,然后以某种方式循环遍历值以找到。dict
`dict['level5', 'level2']
dict`
但是,由于我所使用的数据对象还没有遇到这个问题,所以我没有花时间去尝试解决这个“问题”。
解决方案 24:
将您的词典转换为NestedDict
from ndicts.ndicts import NestedDict
dictionary1 = {'level1': {'level2': {'levelA': 0, 'levelB': 1}}}
update = {'level1': {'level2': {'levelB': 10}}}
nd, nd_update = NestedDict(dictionary1), NestedDict(update)
然后只需使用更新
>>> nd.update(nd_update)
>>> nd
NestedDict({'level1': {'level2': {'levelA': 0, 'levelB': 10}}})
如果你需要字典形式的结果nd.to_dict()
安装ndicts pip install ndicts
解决方案 25:
d
是需要更新的字典,u
是 dict-updater。
def recursively_update_dict(d: dict, u: dict):
for k, v in u.items():
if isinstance(v, dict):
d.setdefault(k, {})
recursively_update_dict(d[k], v)
else:
d[k] = v
或者对于 defaultdict
from collections import defaultdict
def recursively_update_defaultdict(d: defaultdict[dict], u: dict):
for k, v in u.items():
if isinstance(v, dict):
recursively_update_dict(d[k], v)
else:
d[k] = v
解决方案 26:
基本解决方案(以防有人来这里寻找)
dictionary1 = {
"level1": {
"level2": {"levelA": 0, "levelB": 1}
}
}
dictionary1.update({
"level1": {
"level2": {
**dictionary1["level1"]["level2"],
"levelB": 10
}
}
})
结果:
{'level1': {'level2': {'levelA': 0, 'levelB': 10}}}
解决方案 27:
以下是我使用的:
from collections.abc import MutableMapping as Map
def merge(d, v):
"""
Merge two dictionaries.
Merge dict-like `v` into dict-like `d`. In case keys between them
are the same, merge their sub-dictionaries. Otherwise, values in
`v` overwrite `d`.
"""
for key in v:
if key in d and isinstance(d[key], Map) and isinstance(v[key], Map):
d[key] = merge(d[key], v[key])
else:
d[key] = v[key]
return d
merge(dictionary1, update)
print(dictionary1)
>>> {'level1': {'level2': {'levelA': 0, 'levelB': 10}}}
解决方案 28:
@kepler 的回答对我有帮助,但是当我跑步时
from pydantic.utils import deep_update
dict1 = deep_update(dict1, dict2)
出现警告:
UserWarning: `pydantic.utils:deep_update` has been removed. We are importing from `pydantic.v1.utils:deep_update` instead.See the migration guide for more details: https://docs.pydantic.dev/latest/migration/
f'`{import_path}` has been removed. We are importing from `{new_location}` instead.'
因此我将导入命令改为
from pydantic.v1.utils import deep_update
解决方案 29:
dictionary1 = {
"level1": {
"level2": {"levelA": 0, "levelB": 1}
}
}
update = {
"level1": {
"level2": {"levelB": 10}
}
}
from pydash import py_
print(py_.merge(dictionary1, update))
输出:{'level1':{'level2':{'levelA':0,'levelB':10}}}
解决方案 30:
部分感谢这里的答案,我能够想出一个向字典中添加项目的解决方案,包括将项目添加到字典中的列表值中(如果它们尚未在列表中)。
Python 3:
import collections.abc
def dict_update(d, u, fixed=False):
for k, v in u.items():
if isinstance(v, collections.abc.Mapping):
if k in d.keys() or not fixed:
d[k] = dict_update(d.get(k, {}), v, fixed=fixed)
elif isinstance(v, list):
if k in d.keys() or not fixed:
# Iterate through list value and add item if not already in list
for i in v:
if i not in d.get(k, []):
d[k] = d.get(k, []) + [i]
else:
if k in d.keys() or not fixed:
d[k] = v
return d
dictionary1 = {
"level1": {
"level2": {"levelA": 0, "levelB": 1},
"level3": ["itemA", "itemB"]
}
}
update = {
"level1": {
"level2": {"levelB": 10},
"level3": ["itemC"]
}
}
updated_dict = dict_update(dictionary1, update, fixed=False)
print(updated_dict)
>>> {'level1': {'level2': {'levelA': 0, 'levelB': 10}, 'level3': ['itemA', 'itemB', 'itemC']}}
如果fixed=True
,输入字典d
将是固定的,并且只有当键已经存在于原始字典中时才会更新值,因此不会添加新的键。