我有一个JSON对象,我想遍历它并检查/更新所有的字符串叶节点。我不知道JSON的深度(它是嵌套用户界面的表示),所以我想递归地遍历JSON对象。
下面的代码演示了我想要做的事情,我尝试过几次不同的尝试(https://nvie.com/posts/modifying-deeply-nested-structures/),但我似乎无法正确地完成它。我要么得到一个“在迭代过程中更改大小的字典”,要么得到一个‘键必须是str、int、float、bool或not,而不是tuple’的错误。
import json
# function for iterating through every JSON item
def walk(obj, parent_first=True):
# Top down?
if parent_first:
yield (), obj
# For nested objects, the key is the path component.
if isinstance(obj, dict):
children = obj.items()
# For nested lists, the position is the path component.
elif isinstance(obj, (list, tuple)):
children = enumerate(obj)
# Scalar values have no children.
else:
children = []
# Recurse into children
for key, value in children:
for child_path, child in walk(value, parent_first):
yield (key,) + child_path, child
# Bottom up?
if not parent_first:
yield (), obj
def Test():
response = """
{
"Name":"Mixed Listbox",
"Type":"ListBox",
"Visible?":true,
"Enabled State":"Enabled",
"Value":0,
"All Items":[
"Non-Unicode",
"FFFE55006E00690063006F0064006500"
]
}
"""
response = json.loads(response)
# iterate through each item in the JSON object and update the string items
for path, value in walk(response):
# if the JSON item is a string
if isinstance(value,str):
# update the string value
response[path] = 'string: ' + valueTraceback (most recent call last): File "<string>", line 56, in <module> File "<string>", line 50, in Test File "<string>", line 23, in walk RuntimeError: dictionary changed size during iteration预期输出
response = """
{
"Name":"string: Mixed Listbox",
"Type":"string: ListBox",
"Visible?":true,
"Enabled State":"string: Enabled",
"Value":0,
"All Items":[
"string: Non-Unicode",
"string: FFFE55006E00690063006F0064006500"
]
}
"""发布于 2021-04-08 09:28:23
这是我实现的最后一个解决方案,它没有使用泛型的‘was’函数,但它通过JSON对象进行递归,并更新任何字符串项。我遗漏的部分是返回和更新对象,而不是尝试返回路径,然后更新它。
# converts unicode hex strings into strings for known types in the return data
def handleUnicode(self,response):
def decode_dict(obj):
# if dict, children are items
if isinstance(obj,dict):
children = obj.items()
# if list/tuple, enumerate items
elif isinstance(obj,(list,tuple)):
children = enumerate(obj)
# scalar values have no children
else:
children = []
# if the obj is a string, decode it
if isinstance(obj,str):
obj = self.decodeBomHexString(obj)
# iterate through the children (recursively)
for key,value in children:
obj[key] = decode_dict(value)
return obj
response = decode_dict(response)
return responsehttps://stackoverflow.com/questions/66987975
复制相似问题