根据条件递归地向嵌套字典中添加键



我有一个多级嵌套字典,每当字典中有type键时,试图添加一个键required

代码:

def add_recursively(val):
if 'type' in val and val['type'] != 'object':
val['required'] = False
return val
elif 'type' in val and val['type'] == 'object' and 'object_schema' in val:
return add_recursively(val['object_schema'])
else:
val['required'] = False
return val
new_data = {}
for key, value in data.items():
if value['type'] == 'object' and 'object_schema' in value:
new_data[key] = add_recursively(value)
else:
value['required'] = False
new_data[key] = value

输入数据:

data = {'key1': {'description': 'Configuration for OpenID', 'type': 'boolean'},
'key2': {'default': {'enabled': True, 'logging_percent': 100},
'object_schema': {'enabled': {'default': True, 'type': 'boolean'},
'logging_percent': {'default': 100, 'type': 'float'},
'nested_key': {'default': {'new_enable': True, 'new_precent': 100},
'object_schema': {'new_enable': {'default': True, 'type': 'boolean'},
'new_precent': {'default': 100, 'type': 'float'}},
'type': 'object'}},
'type': 'object'}}

输出数据:

{'key1': {'description': 'Configuration for OpenID',
'required': False,
'type': 'boolean'},
'key2': {'enabled': {'default': True, 'type': 'boolean'},
'logging_percent': {'default': 100, 'type': 'float'},
'nested_key': {'default': {'new_enable': True, 'new_precent': 100},
'object_schema': {'new_enable': {'default': True, 'type': 'boolean'},
'new_precent': {'default': 100, 'type': 'float'}},
'type': 'object'},
'required': False}}

预期输出:

{'key1': {
'required': False,
'description': 'Configuration for OpenID',
'type': 'boolean'},
'key2': {
'required': False,
'enabled': {'required': False, 'default': True, 'type': 'boolean'},
'logging_percent': {'required': False, 'default': 100, 'type': 'float'},
'nested_key': {'default': {'new_enable': True, 'new_precent': 100},
'object_schema': {'new_enable': {'required': False, 'default': True, 'type': 'boolean'},
'new_precent': {'required': False, 'default': 100, 'type': 'float'}},
'type': 'object'},
}}

这里有一种修改data的方法,即将required键添加到包含type键的每个键中:

def add_required(d):
if 'type' in d:
d['required'] = False
for v in d.values():
if isinstance(v, dict):
add_required(v)
add_required(data)

输出:

>>> data
{'key1': {'description': 'Configuration for OpenID',
'type': 'boolean',
'required': False},
'key2': {'default': {'enabled': True, 'logging_percent': 100},
'object_schema': {'enabled': {'default': True,
'type': 'boolean',
'required': False},
'logging_percent': {'default': 100, 'type': 'float', 'required': False},
'nested_key': {'default': {'new_enable': True, 'new_precent': 100},
'object_schema': {'new_enable': {'default': True,
'type': 'boolean',
'required': False},
'new_precent': {'default': 100, 'type': 'float', 'required': False}},
'type': 'object',
'required': False}},
'type': 'object',
'required': False}}

有多种方法可以解决这个问题(每种方法各有利弊),这里有一种方法可以创建(嵌套)对象的副本。

code00.py:

#!/usr/bin/env python
import sys
from pprint import pprint as pp

data = {
"key1": {"description": "Configuration for OpenID", "type": "boolean"},
"key2": {
"default": {
"enabled": True, "logging_percent": 100,
},
"object_schema": {
"enabled": {"default": True, "type": "boolean"},
"logging_percent": {"default": 100, "type": "float"},
"nested_key": {
"default": {"new_enable": True, "new_precent": 100},
"object_schema": {
"new_enable": {"default": True, "type": "boolean"},
"new_precent": {"default": 100, "type": "float"},
},
"type": "object",
}
},
"type": "object",
}
}

def add_rec(orig_data, new_items):
ret = {}
for k, v in orig_data.items():
if k == "type":
ret.update(new_items)
if isinstance(v, dict):
ret[k] = add_rec(v, new_items)
else:
ret[k] = v
return ret

def main(*argv):
new_data = add_rec(data, {"required": False})
pp(new_data)

if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}n".format(" ".join(elem.strip() for elem in sys.version.split("n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("nDone.")
sys.exit(rc)

:

cfati@CFATI-5510-0:e:WorkDevStackOverflowq072213710]> "e:WorkDevVEnvspy_pc064_03.09_test0Scriptspython.exe" code00.py
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32
{'key1': {'description': 'Configuration for OpenID',
'required': False,
'type': 'boolean'},
'key2': {'default': {'enabled': True, 'logging_percent': 100},
'object_schema': {'enabled': {'default': True,
'required': False,
'type': 'boolean'},
'logging_percent': {'default': 100,
'required': False,
'type': 'float'},
'nested_key': {'default': {'new_enable': True,
'new_precent': 100},
'object_schema': {'new_enable': {'default': True,
      'required': False,
      'type': 'boolean'},
'new_precent': {'default': 100,
       'required': False,
       'type': 'float'}},
'required': False,
'type': 'object'}},
'required': False,
'type': 'object'}}
Done.

相关内容

  • 没有找到相关文章

最新更新