Python 如何更新嵌套在另一个目录中的dict?
我有以下原文:Python 如何更新嵌套在另一个目录中的dict?,python,dictionary,recursion,Python,Dictionary,Recursion,我有以下原文: {'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'" }, 'calibration': True, 'target_v
{'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'",
'END_DT': "'202104'"
},
'calibration': True,
'target_variable': 'unsure'}}
我想用以下命令替换set params位:
dict1= {'set_params': {'START_DT': "'201001'",
'END_DT': "'201004'"
}}
我从一个类似的问题中得到了这个代码:
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
update(original,dict1)
将其应用于上面,我得到:
{'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'",
'END_DT': "'202104'"
},
'calibration': True,
'target_variable': 'unsure'},
'set_params': {'START_DT': "'201001'",
'END_DT': "'201004'" }}
因此,它没有替换,而是在末尾附加了替换dict。如何更新dict中的值,以便在传递另一个dict时,它会替换dict1?我做错了什么?在dict中,当您将某个内容添加到一个不存在的键上时,它会被追加,然后添加内容。如果你想替换一些密钥,你必须先删除它。
使用pop键删除您的dict.pop键,然后您可以正常添加另一个键。在dict中,当您向一个不存在的键添加某个内容时,会追加该内容,然后添加内容。如果你想替换一些密钥,你必须先删除它。
对要删除的yourdict.pop键使用pop,然后您可以正常添加另一个键。现在Python dict有一个更新方法,可以从另一个dict更新。请确保指定要更新和更新的相应dict
original['data_extraction']['set_params'].update(dict1['set_params'])
或者可能
original['data_extraction'].update(dict1)
如果dict1中除了“set_params”之外还有其他键,并且您也希望更新这些键。现在Python dict有一个更新方法可以从另一个dict更新。请确保指定要更新和更新的相应dict
original['data_extraction']['set_params'].update(dict1['set_params'])
或者可能
original['data_extraction'].update(dict1)
如果在dict1中除了“set_params”之外还有其他键,并且您也希望更新这些键。使用dict.update的递归函数。这样,在使用多级字典时,就不必指定键
def update_dict(source_dict, dict1):
for key in source_dict:
if key in dict1.keys():
source_dict.update(dict1)
elif isinstance(source_dict[key],dict):
update_dict(source_dict[key], dict1)
source_dict = {'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'",
'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}}
dict1= {'set_params': {'START_DT': "'201001'",
'END_DT': "'201004'"
}}
update_dict(source_dict, dict1)
print(source_dict)
>>
{'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"},
'calibration': True,
'target_variable': 'unsure'}}
from copy import deepcopy
def update(d, u):
r = deepcopy(d)
for k, v in r.items():
if type(v) is dict:
for _k, _v in v.items():
if _k in u:
r[k][_k] = u[_k]
elif k in u:
r[k] = u[k]
return r
a = {'data_extraction':{'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}
}
b = {'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
c = update(a, b)
print(a, '\n')
print(b, '\n')
print(c, '\n')
将递归函数与dict.update一起使用。这样,在使用多级字典时,就不必指定键
def update_dict(source_dict, dict1):
for key in source_dict:
if key in dict1.keys():
source_dict.update(dict1)
elif isinstance(source_dict[key],dict):
update_dict(source_dict[key], dict1)
source_dict = {'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'",
'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}}
dict1= {'set_params': {'START_DT': "'201001'",
'END_DT': "'201004'"
}}
update_dict(source_dict, dict1)
print(source_dict)
>>
{'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"},
'calibration': True,
'target_variable': 'unsure'}}
from copy import deepcopy
def update(d, u):
r = deepcopy(d)
for k, v in r.items():
if type(v) is dict:
for _k, _v in v.items():
if _k in u:
r[k][_k] = u[_k]
elif k in u:
r[k] = u[k]
return r
a = {'data_extraction':{'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}
}
b = {'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
c = update(a, b)
print(a, '\n')
print(b, '\n')
print(c, '\n')
你就快到了。。。在这个实现中,我使用deepcopy来避免覆盖原始字典
def update_dict(source_dict, dict1):
for key in source_dict:
if key in dict1.keys():
source_dict.update(dict1)
elif isinstance(source_dict[key],dict):
update_dict(source_dict[key], dict1)
source_dict = {'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'",
'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}}
dict1= {'set_params': {'START_DT': "'201001'",
'END_DT': "'201004'"
}}
update_dict(source_dict, dict1)
print(source_dict)
>>
{'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"},
'calibration': True,
'target_variable': 'unsure'}}
from copy import deepcopy
def update(d, u):
r = deepcopy(d)
for k, v in r.items():
if type(v) is dict:
for _k, _v in v.items():
if _k in u:
r[k][_k] = u[_k]
elif k in u:
r[k] = u[k]
return r
a = {'data_extraction':{'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}
}
b = {'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
c = update(a, b)
print(a, '\n')
print(b, '\n')
print(c, '\n')
输出:
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"}, 'calibration': True, 'target_variable': 'unsure'}}
{'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}, 'calibration': True, 'target_variable': 'unsure'}}
{
"data_extraction": {
"if_extraction": false,
"path_data": "data_extraction/extractions.sql",
"set_params": {
"START_DT": "'201001'",
"END_DT": "'201004'"
},
"calibration": true,
"target_key_variable": "unsure"
}
}
你就快到了。。。在这个实现中,我使用deepcopy来避免覆盖原始字典
def update_dict(source_dict, dict1):
for key in source_dict:
if key in dict1.keys():
source_dict.update(dict1)
elif isinstance(source_dict[key],dict):
update_dict(source_dict[key], dict1)
source_dict = {'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'",
'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}}
dict1= {'set_params': {'START_DT': "'201001'",
'END_DT': "'201004'"
}}
update_dict(source_dict, dict1)
print(source_dict)
>>
{'data_extraction': {'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"},
'calibration': True,
'target_variable': 'unsure'}}
from copy import deepcopy
def update(d, u):
r = deepcopy(d)
for k, v in r.items():
if type(v) is dict:
for _k, _v in v.items():
if _k in u:
r[k][_k] = u[_k]
elif k in u:
r[k] = u[k]
return r
a = {'data_extraction':{'if_extraction': False,
'path_data': 'data_extraction/extractions.sql',
'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"},
'calibration': True,
'target_variable': 'unsure'}
}
b = {'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
c = update(a, b)
print(a, '\n')
print(b, '\n')
print(c, '\n')
输出:
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"}, 'calibration': True, 'target_variable': 'unsure'}}
{'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}, 'calibration': True, 'target_variable': 'unsure'}}
{
"data_extraction": {
"if_extraction": false,
"path_data": "data_extraction/extractions.sql",
"set_params": {
"START_DT": "'201001'",
"END_DT": "'201004'"
},
"calibration": true,
"target_key_variable": "unsure"
}
}
您需要让递归函数检查每个嵌套字典,看看它是否包含需要替换为目标_键的键。在下面的代码中,这是从传递给update函数的替换字典参数new_dict中检索的。这只需要执行一次,因此有一个嵌套的_update函数来执行实际的替换
import collections.abc
original = {
"data_extraction": {
"if_extraction": False,
"path_data": "data_extraction/extractions.sql",
"set_params": {
"START_DT": "'201901'",
"END_DT": "'202104'"
},
"calibration": True,
"target_key_variable": "unsure"
}
}
dict1 = {
"set_params": {
"START_DT": "'201001'",
"END_DT": "'201004'"
}
}
def update(d, new_dict):
target_key, new_value = list(new_dict.items())[0]
def nested_update(d, new_dict):
for key, value in d.items():
if key == target_key:
d[key] = new_value
elif isinstance(value, collections.abc.Mapping):
d[key] = nested_update(value, new_dict)
return d
nested_update(d, new_dict)
return d
update(original, dict1)
import json
print(json.dumps(original, indent=2)) # Pretty-print result.
输出:
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"}, 'calibration': True, 'target_variable': 'unsure'}}
{'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}, 'calibration': True, 'target_variable': 'unsure'}}
{
"data_extraction": {
"if_extraction": false,
"path_data": "data_extraction/extractions.sql",
"set_params": {
"START_DT": "'201001'",
"END_DT": "'201004'"
},
"calibration": true,
"target_key_variable": "unsure"
}
}
您需要让递归函数检查每个嵌套字典,看看它是否包含需要替换为目标_键的键。在下面的代码中,这是从传递给update函数的替换字典参数new_dict中检索的。这只需要执行一次,因此有一个嵌套的_update函数来执行实际的替换
import collections.abc
original = {
"data_extraction": {
"if_extraction": False,
"path_data": "data_extraction/extractions.sql",
"set_params": {
"START_DT": "'201901'",
"END_DT": "'202104'"
},
"calibration": True,
"target_key_variable": "unsure"
}
}
dict1 = {
"set_params": {
"START_DT": "'201001'",
"END_DT": "'201004'"
}
}
def update(d, new_dict):
target_key, new_value = list(new_dict.items())[0]
def nested_update(d, new_dict):
for key, value in d.items():
if key == target_key:
d[key] = new_value
elif isinstance(value, collections.abc.Mapping):
d[key] = nested_update(value, new_dict)
return d
nested_update(d, new_dict)
return d
update(original, dict1)
import json
print(json.dumps(original, indent=2)) # Pretty-print result.
输出:
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"}, 'calibration': True, 'target_variable': 'unsure'}}
{'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}
{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}, 'calibration': True, 'target_variable': 'unsure'}}
{
"data_extraction": {
"if_extraction": false,
"path_data": "data_extraction/extractions.sql",
"set_params": {
"START_DT": "'201001'",
"END_DT": "'201004'"
},
"calibration": true,
"target_key_variable": "unsure"
}
}
但是replacment dict包含存在的键,那么为什么要追加?键在子dict中重复,唯一起作用的键是用于将其添加到列表中的键。我如何升级函数以在任何位置找到它(例如嵌套或未嵌套)?要更新的数据在数据提取内部,只需在此处更新即可。原始[data_extraction][START_DT]=dict1[set_params][START_DT]但重放dict包含存在的键,为什么要追加?这些键在子dict中重复,唯一起作用的键是用于将其添加到列表中的键。我如何升级该函数以在任何位置找到它,例如嵌套或不嵌套?要更新的数据在数据提取内部,只需在那里更新即可。原始[数据提取][开始提取]=dict1[设置参数][开始提取]这起作用,但是,是否没有一种程序化的更新方式,因此我不必指定数据提取?我有点希望能够以一种不必指定键的方式来完成它。@Maths12我同意了。这就是为什么这里需要递归函数。检查我下面的答案。这是可行的,但是没有一种程序化的更新方式,所以我不必指定数据提取?我有点希望能够以一种不必指定键的方式来完成它。@Maths12我同意了。这就是为什么这里需要递归函数。检查我下面的答案。谢谢。如果我没有将源代码dict作为参数传递,那么我有:def update_dict_originaldict1:source_dict=original for key in source_dict:if key in dict1.keys:source_dict.updatedict1 elif is instancesource_dict[key],dict:update\u dict\u originaldict1返回源代码\u dict-i在代码中出现递归错误,因为它是一个递归函数source\u dict=original,所以每次函数调用都会执行。谢谢,如果我没有将source dict作为参数传递,那么我有:def update\u dict\u originaldict1:source\u dict=original for key in source\u dict:if key in dict1.keys:source\u dict.updatedict1 elifisinstancesource_dict[键],dict:更新_dict_原点
aldict1 return source_dict-i get recursion ERROR在您的代码中,因为它是一个递归函数source_dict=original,在每次函数调用中都会执行。