TLDR
您可以使用dict.setdefault
or collections.defaultdict
.
def make_path(d: dict, *paths: str) -> None:
for key in paths:
d = d.setdefault(key, {})
make_path(my_dict, 'path-to', 'my', 'keys')
assert my_dict['path-to']['my']['keys'] is not None
详细信息
解决方案1。dict.setdefault
:
my_dict.setdefault('path-to', {}).setdefault('my', {}).setdefault('keys', {})
Pros:
-
my_dict
是正常的dict
- 使 dict 仅显式发生
- 无深度限制
Cons:
解决方案2。collections.defaultdict
:
from collections import defaultdict
my_dict = defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))
my_dict['path-to']['my']['keys']
Pros:
Cons:
- 字典的制作是隐式发生的。
-
my_dict
不纯粹dict
.
- 根据定义,您有深度限制
my_dict
.
解决方案 3. 解决方案 1 的高级:创建自己的函数
def make_path(my_dict: dict, *paths: str) -> dict:
while paths:
key, *paths = paths
my_dict = my_dict.setdefault(key, {})
return my_dict
test = {'path-to': {'test': 1}}
print(test)
make_path(test, 'path-to', 'my', 'keys')['test2'] = 4
print(test)
print(make_path(test)) # It's okay even no paths passed
output:
{'path-to': {'test': 1}}
{'path-to': {'test': 1, 'my': {'keys': {'test2': 4}}}}
{'path-to': {'test': 1, 'my': {'keys': {'test2': 4}}}}
解决方案 4. 解决方案 2 的高级:创建您自己的类
class MyDefaultDict(dict):
def __missing__(self, key):
self[key] = MyDefaultDict()
return self[key]
my_dict = MyDefaultDict()
print(my_dict)
my_dict['path-to']['my']['keys'] = 'hello'
print(my_dict)
output:
{}
{'path-to': {'my': {'keys': 'hello'}}}
结论
我觉得解决方案3与您的需求最相似,但如果适合您的情况,您可以使用任何其他选项。
Append
在解决方案 4 中,我们已经从 json 解析出了 dict :d 怎么样?您的解决方案从 MyDefaultDict() 类型开始,而不是从 jsons.loads() 返回的类型开始
如果你可以编辑json.loads
部分,然后尝试:
import json
class MyDefaultDict(dict):
def __missing__(self, key):
self[key] = MyDefaultDict()
return self[key]
data = '{"path-to": {"my": {"keys": "hello"}}}'
my_dict = json.loads(data, object_pairs_hook=MyDefaultDict)
print(type(my_dict))
output:
<class '__main__.MyDefaultDict'>