[英]Edit dict recursively in Python
我有這樣的字典
{
"library": [
{
"_type": "Host",
"parameters": "JSON STRING",
"superclassOf": [
{
"_type": "LinuxHost",
"superclassOf": [
{
"_type": "Ubuntu",
"superclassOf": [
{
"_type": "Ubuntu1604",
"parameters": "JSON STRING"
}
]
}
]
}
]
}
]
}
其中JSON STRING
是字符串形式的字典(例如'{"property1":"value1","property2":"value2"}'
)。 我正在尋找的是一種遞歸導航supeclassOf
屬性並將這些 Json 字符串轉換為 json 的實部的方法,並在編輯后返回完整的字典。
編輯:請注意supeclassOf
的值是列表。 所以到處都有一個superclassOf
可以有多個元素,每個元素都有(或沒有)屬性parameters
和superclassOf
EDIT2使用 Prem Anand 的回答我得到這個錯誤:
Traceback (most recent call last):
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 61, in <module>
main()
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 52, in main
process_list_or_dict(library)
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 45, in process_list_or_dict
process_list_or_dict(v)
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 45, in process_list_or_dict
process_list_or_dict(v)
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 45, in process_list_or_dict
process_list_or_dict(v)
[Previous line repeated 5 more times]
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 43, in process_list_or_dict
ld[k] = process_str(v)
File "C:/Users/ceccolig/PycharmProjects/api/api.py", line 37, in process_str
return json.loads(s)
File "C:\Users\ceccolig\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "C:\Users\ceccolig\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\ceccolig\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
您可以使用json.loads
將 json 字符串轉換為字典。 瀏覽 dict 的每個元素,檢查它是 dict 還是 list 或 string 類型並相應地處理每種類型
import json
def process_str(s):
if s and s[0]=='{' and s[-1]=='}':
return json.loads(s)
return s
def process_list_or_dict(ld):
for k,v in enumerate(ld) if isinstance(ld, list) else ld.items():
if isinstance(v, str):
ld[k] = process_str(v)
elif isinstance(v, (list, dict)):
process_list_or_dict(v)
例子
dct = {'library': [{'_type': 'Host', 'parameters': '{"property1":"value1","property2":"value2"}', 'superclassOf': [{'_type': 'LinuxHost', 'superclassOf': [{'_type': 'Ubuntu', 'superclassOf': [{'_type': 'Ubuntu1604', 'parameters': '{"property3":"value3","property4":"value4"}'}]}]}]}]}
process_list_or_dict(dct)
print(json.dumps(dct, indent=4))
Output
{
"library": [
{
"_type": "Host",
"parameters": {
"property1": "value1",
"property2": "value2"
},
"superclassOf": [
{
"_type": "LinuxHost",
"superclassOf": [
{
"_type": "Ubuntu",
"superclassOf": [
{
"_type": "Ubuntu1604",
"parameters": {
"property3": "value3",
"property4": "value4"
}
}
]
}
]
}
]
}
]
}
好的,我希望你現在明白了。 參考這個問題,我修改了答案以使其對您有用。 希望這就是您要找的:
import json
data = {
"library": [
{
"_type": "Host",
"parameters": '{"property1":"value1","property2":"value2"}',
"superclassOf": [
{
"_type": "LinuxHost",
"superclassOf": [
{
"_type": "Ubuntu",
"superclassOf": [
{
"_type": "Ubuntu1604",
"parameters": '{"property1":"value1","property2":"value2"}'
}
]
}
]
}
]
}
]
}
# if you want to modify a specific key's value where you only know the key
def replace(data, key_match, repl):
if isinstance(data, dict):
return {k: replace((v if k != key_match else repl), key_match, repl) for k, v in data.items()}
elif isinstance(data, list):
return [replace(i, key_match, repl) for i in data]
elif isinstance(data, str):
try:
data = json.loads(data)
return replace(data, key_match, repl)
except ValueError:
return data
else:
return data
print(replace(data, "property1", "Modified"))
# {'library': [{'_type': 'Host', 'parameters': {'property1': 'Modified', 'property2': 'value2'}, 'superclassOf': [{'_type': 'LinuxHost', 'superclassOf': [{'_type': 'Ubuntu', 'superclassOf': [{'_type': 'Ubuntu1604', 'parameters': {'property1': 'Modified', 'property2': 'value2'}}]}]}]}]}
編輯
如果只想轉換json。
def convertJSON(data):
if isinstance(data, dict):
return {k: convertJSON(v) for k, v in data.items()}
elif isinstance(data, list):
return [convertJSON(i) for i in data]
elif isinstance(data, str):
try:
data = json.loads(data)
return convertJSON(data)
except ValueError:
return data
else:
return data
print(convertJSON(data))
# {'library': [{'_type': 'Host', 'parameters': {'property1': 'value1', 'property2': 'value2'}, 'superclassOf': [{'_type': 'LinuxHost', 'superclassOf': [{'_type': 'Ubuntu', 'superclassOf': [{'_type': 'Ubuntu1604', 'parameters': {'property1': 'value1', 'property2': 'value2'}}]}]}]}]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.