json - 如何遍历 JSON
问题描述
我目前正在研究一个步行 json,我可以在其中添加参数,在步行中添加我想要通过 JSON 的步行。我创造了这样的东西:
from collections import abc
def walk(obj, *path):
"""
Goes through the given json path. If it is found then return the given path else empty dict
"""
for segment in path:
if not isinstance(obj, abc.Mapping) or segment not in obj:
print(f"Couldn't walk path; {path}")
return {}
obj = obj[segment]
return obj
# -------------------------------------------------------- #
json_value = {
"id": "dc932304-dde4-3517-8b76-58081cc9dd0d",
"Information": [{
"merch": {
"id": "8fb66657-b93d-5f2d-8fe7-a5e355f0f3a8",
"status": "ACTIVE"
},
"value": {
"country": "SE IS BEST"
},
"View": {
"id": "9aae10f4-1b75-481d-ac5f-b17bc46675bd"
}
}],
"collectionTermIds": [
],
"resourceType": "thread",
"rollup": {
"totalThreads": 1,
"threads": [
]
},
"collectionsv2": {
"groupedCollectionTermIds": {
},
"collectionTermIds": [
]
}
}
# -------------------------------------------------------- #
t = walk(json_value, "Information", 0)
print(t)
我目前的问题是,我试图通过为walk
函数提供我提供的值 0 从“信息”中获取列表中的第一个,但是它返回它不能由于Couldn't walk path; ('Information', 0)
我想知道如何通过将其输入参数来选择要遍历的列表编号?例如,如果我选择 1,它应该返回Couldn't walk path; ('Information', 1)
,但如果我选择这样做0
,它应该返回
{
"merch": {
"id": "8fb66657-b93d-5f2d-8fe7-a5e355f0f3a8",
"status": "ACTIVE"
},
"value": {
"country": "SE IS BEST"
},
"View": {
"id": "9aae10f4-1b75-481d-ac5f-b17bc46675bd"
}
}
解决方案
这应该适用于任何 JSON 对象:
def walk(obj, *path):
"""
Goes through the given json path. If it is found then return the given path else empty dict
"""
try:
segment, key, *rest = path
except ValueError:
# We are simply passed in a single key, ex. walk(obj, 'my_key')
key = path[0]
try:
return obj[key]
except KeyError:
print(f"Couldn't walk path: {key!r}\n"
f" obj={obj!r}\n"
" reason=key missing from object")
return {}
except TypeError:
print(f"Couldn't walk path: {key!r}\n"
f" obj={obj!r}\n"
" reason=object is not a mapping or array type.")
return {}
except IndexError as e:
print(f"Couldn't walk path: {key!r}\n"
f" obj={obj!r}\n"
f" reason={e}")
return {}
# This indicates we want to walk down a nested (or deeply nested) path. We
# can use recursion to solve this case.
try:
inner_obj = obj[segment]
except KeyError:
print(f"Couldn't walk path: {segment!r} -> {key!r}\n"
f" obj={obj!r}\n"
" reason=key missing from object")
return {}
except IndexError as e:
print(f"Couldn't walk path: {segment!r} -> {key!r}\n"
f" obj={obj!r}\n"
f" reason={e}")
return {}
else:
return walk(inner_obj, key, *rest)
这可能会被优化一点,例如通过except
稍微修改删除重复的块。
测试代码(使用json_value
上面的代码):
t = walk(json_value, 'Information', 1)
assert t == {}
t = walk(json_value, 'Information', 1, 'value', 'country')
assert t == {}
t = walk(json_value, 'Information', 0)
print(t)
# {'merch': {'id': '8fb66657-b93d-5f2d-8fe7-a5e355f0f3a8', 'status': 'ACTIVE'}, 'value': {'country': 'SE IS BEST'}, 'View': {'id': '9aae10f4-1b75-481d-ac5f-b17bc46675bd'}}
t = walk(json_value, 'Information', 0, 'value', 'country')
print(t)
# SE IS BEST
t = walk(json_value, 'collectionsv2', 'collectionTermIds')
print(t)
# []
t = walk(json_value, 'id')
print(t)
# dc932304-dde4-3517-8b76-58081cc9dd0d
t = walk(json_value, 'id', 'test')
assert t == {}
# error: wrong type
推荐阅读
- gitlab - gitlab如何在一台机器上并行运行多个管道?
- powershell - 使用计划任务根据文件名将文件移动到特定的 YY-MM 文件夹中
- cookies - 如何让 cookie 正确地与 Nuxt Apollo 和 SSR 一起使用?
- java - 列表大小由于某种原因回到零
- android - 带有未生成参数的android NavDirections构造函数
- flutter - 为什么颤振在运行时显示多个过去的错误?
- apache-spark - 在pyspark中添加数据类型为字符串格式的两列的值
- registry - Chromium 策略:我的 PC 和 VM Ware 的差异
- jboss - Drools-如何获得触发规则的事实?
- django - Django is_valid() 总是返回 false 错误