如果键在列表中,如何更新嵌套字典中的值? [英] How to update values in nested dictionary if keys are in a list?
问题描述
假设我有一个钥匙清单
key_lst = ["key1", "key2", "key3"]
我有一个价值
value = "my_value"
以及具有此结构的示例dict my_dict
and an example dict my_dict
with this structure
{
"key1": {
"key2": {
"key3": "some_value"
}
},
}
如何通过遍历/遍历key_lst
来动态地将变量value
中的新值分配给my_dict["key1"]["key2"]["key3"]
?
How can I dynamically assign the new value in variable value
to my_dict["key1"]["key2"]["key3"]
by going thru / looping over my key_lst
?
我不能只说my_dict["key1"]["key2"]["key3"] = value
,因为键和键的数量正在变化.我总是在列表中获取键(我必须将值保存到的路径)...
I can not just say my_dict["key1"]["key2"]["key3"] = value
since the keys and the number of keys is changing. I always get the keys (the path that i have to save the value at) in a list...
我正在寻找的输出是{'key1': {'key2': {'key3': 'my_value'}}}
.字典结构是预定义的.
The output I am looking for is {'key1': {'key2': {'key3': 'my_value'}}}
. The dictionary structure is predefined.
我正在使用Python 3.7
I'm using Python 3.7
推荐答案
预定义的字典结构: functools.reduce
您可以使用functools.reduce
定义一个函数来重复应用getitem
,然后设置一个提供的值:
Predefined dictionary structure: functools.reduce
You can define a function using functools.reduce
to apply getitem
repeatedly and then set a supplied value:
from functools import reduce
from operator import getitem
def set_nested_item(dataDict, mapList, val):
"""Set item in nested dictionary"""
reduce(getitem, mapList[:-1], dataDict)[mapList[-1]] = val
return dataDict
key_lst = ["key1", "key2", "key3"]
value = "my_value"
d = {"key1": {"key2": {"key3": "some_value"}}}
d = set_nested_item(d, key_lst, value)
print(d)
# {'key1': {'key2': {'key3': 'my_value'}}}
注意operator.getitem
用于访问dict.__getitem__
或其更常用的语法糖dict[]
.在这种情况下,functools.reduce
在dataDict
上递归调用getitem
,依次使用mapList[:-1]
中的每个值作为参数.对于[:-1]
,我们有意省略了最后一个值,因此我们可以通过dict[key] = value
将__setitem__
用作最终键.
Note operator.getitem
is used to access dict.__getitem__
, or its more commonly used syntactic sugar dict[]
. In this instance, functools.reduce
calls getitem
recursively on dataDict
, successively using each value in mapList[:-1]
as an argument. With [:-1]
, we intentionally leave out the last value, so we can use __setitem__
via dict[key] = value
for the final key.
如果希望在尚未定义的任意分支处添加项目,则可以构造defaultdict
.为此,您可以先 defaultify
您的常规词典输入,然后像以前一样使用set_nested_item
:
If you wish to add items at arbitrary branches not yet been defined, you can construct a defaultdict
. For this, you can first defaultify
your regular dictionary input, then use set_nested_item
as before:
from collections import defaultdict
def dd_rec():
return defaultdict(dd_rec)
def defaultify(d):
if not isinstance(d, dict):
return d
return defaultdict(dd_rec, {k: defaultify(v) for k, v in d.items()})
dd = defaultify(d)
key_lst = ["key1", "key2", "key5", "key6"]
value = "my_value2"
dd = set_nested_item(dd, key_lst, value)
print(dd)
# defaultdict(<function __main__.<lambda>>,
# {'key1': defaultdict(<function __main__.<lambda>>,
# {'key2': defaultdict(<function __main__.<lambda>>,
# {'key3': 'my_value',
# 'key5': defaultdict(<function __main__.<lambda>>,
# {'key6': 'my_value2'})})})})
这篇关于如果键在列表中,如何更新嵌套字典中的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!