Dav*_*yer 4 python dictionary nested python-3.x
假设我有一个键列表
key_lst = ["key1", "key2", "key3"]
Run Code Online (Sandbox Code Playgroud)
我有一个价值
value = "my_value"
Run Code Online (Sandbox Code Playgroud)
以及my_dict具有此结构的示例dict
{
"key1": {
"key2": {
"key3": "some_value"
}
},
}
Run Code Online (Sandbox Code Playgroud)
如何通过遍历/循环value来动态地将变量中的新值分配给?my_dict["key1"]["key2"]["key3"]key_lst
我不能只说my_dict["key1"]["key2"]["key3"] = value因为钥匙和钥匙的数量正在改变.我总是在列表中获取密钥(我必须保存值的路径)...
我正在使用Python 3.7
functools.reduce您可以使用重复functools.reduce应用定义函数getitem,然后设置提供的值:
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'}}}
Run Code Online (Sandbox Code Playgroud)
注意operator.getitem用于访问dict.__getitem__,或其更常用的语法糖dict[].在这种情况下,functools.reduce调用getitem递归上dataDict,先后使用中的每个值mapList[:-1]作为参数.有了[:-1],我们故意省去最后一个值,所以我们可以使用__setitem__via dict[key] = value作为最后一个键.
collections.defaultdict如果您希望在尚未定义的任意分支中添加项目,您可以构建一个defaultdict.为此,您可以先defaultify输入常规字典,然后set_nested_item像以前一样使用:
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'})})})})
Run Code Online (Sandbox Code Playgroud)
您可以setdefault在循环中迭代地构建/访问级别:
d = {}
d2 = d
for k in key_lst[:-1]:
d2 = d2.setdefault(k, {})
d2[key_lst[-1]] = value
print(d)
# {'key1': {'key2': {'key3': 'my_value'}}}
Run Code Online (Sandbox Code Playgroud)
d是对您的字典的引用,并且d2是在每次迭代时访问内部级别的一次性引用.