我已经搜索过文档并使用了许多队友的帮助,但是还是无法弄清楚如何用kwargs(在我的例子中)提供的测试函数来替换字典:
模板字典:
{
"id": "id_1234",
"integer_value": 1234,
"level_one": {
"id": 1234,
"foo": "true",
"list_one": [],
"list_two": [
522
],
"url": "http://google.com",
"level_two": {
"thing_one": {
"yes": "false",
"no": "false"
},
"thing_two": {
"yes": "false",
"no": "false"
}
},
"another_field": "true",
"bar": 15000
}
}
递归字典功能:
def update_dictionary(template_dict, **kwargs):
for k, v in kwargs.items():
print(v)
print(isinstance(v, collections.Mapping))
if isinstance(v, collections.Mapping):
print("This is the k value")
print(k)
template_dict[k] = update_dictionary(template_dict.get(k, {}), v)
else:
print("We're going into the else now")
template_dict[k] = v
return template_dict
我在这里从另一个论坛获得了上述功能,但是在传递kwargs时似乎没有用。对于不在嵌套字典的第一级中的任何字段,isinstance检查结果为False。任何帮助表示赞赏!
测试中kwargs通过的线:
new_dict = update_dictionary(template_dict, another_field = 'false', integer_value=12345)
答案 0 :(得分:0)
所以,你需要继续传递kwargs
,否则超过第一级的所有内容都无法取代!这是一个快速而肮脏的演示:
def update_dict(d, **kwargs):
new = {}
for k, v in d.items():
if isinstance(v, dict):
new[k] = update_dict(v, **kwargs)
else:
new[k] = kwargs.get(k, v)
return new
行动中:
In [16]: template
Out[16]:
{'id': 'id_1234',
'integer_value': 1234,
'level_one': {'another_field': 'true',
'bar': 15000,
'foo': 'true',
'id': 1234,
'level_two': {'thing_one': {'no': 'false', 'yes': 'false'},
'thing_two': {'no': 'false', 'yes': 'false'}},
'list_one': [],
'list_two': [522],
'url': 'http://google.com'}}
In [17]: update_dict(template, another_field = 'false', integer_value=12345)
Out[17]:
{'id': 'id_1234',
'integer_value': 12345,
'level_one': {'another_field': 'false',
'bar': 15000,
'foo': 'true',
'id': 1234,
'level_two': {'thing_one': {'no': 'false', 'yes': 'false'},
'thing_two': {'no': 'false', 'yes': 'false'}},
'list_one': [],
'list_two': [522],
'url': 'http://google.com'}}
再次:
In [19]: update_dict(template, another_field = 'false', integer_value=12345, no='FOO')
Out[19]:
{'id': 'id_1234',
'integer_value': 12345,
'level_one': {'another_field': 'false',
'bar': 15000,
'foo': 'true',
'id': 1234,
'level_two': {'thing_one': {'no': 'FOO', 'yes': 'false'},
'thing_two': {'no': 'FOO', 'yes': 'false'}},
'list_one': [],
'list_two': [522],
'url': 'http://google.com'}}
请注意,此实现会返回一个全新的dict
,这是我认为您想要的,因为template
是一个模板,您写道:
new_dict = update_dictionary(template_dict, another_field = 'false', integer_value=12345)
但如果您实际想要就地修改,您只需更改为:
def update_dict(d, **kwargs):
for k, v in d.items():
if isinstance(v, dict):
update_dict(v, **kwargs)
else:
d[k] = kwargs.get(k, v)
我会选择非就地版本...注意,你可以用一个厚颜无耻的单行,但我不推荐它:
def update_dict(d, **kwargs):
return {k:update_dict(v, **kwargs) if isinstance(v, dict) else kwargs.get(k,v) for k,v in d.items()}