[英]Python Top Level JSON Index
我从我正在调用的 API 中获得以下 JSON 文件:
{
"14500": [
{
"5": {
"versionName": "VersionOne",
"expand": "executionSummaries",
"name": "Regression",
"projectId": 15006,
"startDate": "",
"executionSummaries": {
"executionSummary": []
}
},
"7": {
"versionName": "VersionOne",
"expand": "executionSummaries",
"versionId": 14500,
"projectId": 15006,
"startDate": "19/Sep/16",
"executionSummaries": {
"executionSummary": []
}
},
"-1": {
"versionName": "VersionOne",
"expand": "executionSummaries",
"name": "Ad hoc",
"modifiedBy": "",
"projectId": 15006,
"startDate": "",
"executionSummaries": {
"executionSummary": []
}
},
"recordsCount": 3
}
],
"14501": [
{
"-1": {
"versionName": "Version 2",
"expand": "executionSummaries",
"projectId": 15006,
"startDate": "",
"executionSummaries": {
"executionSummary": []
}
},
"recordsCount": 1
}
],
}
我需要遍历顶层和下一层(例如“14500”、“5”、“7”等)以查找键和值。 因此,例如,我需要搜索整个 JSON 文件以找到与“回归”匹配的名称,并找到“ProjectID”和可能的其他字符串的那组数据值。 我以前通过使用 data["level1"][0]["level2"] 等来做到这一点,但在这种情况下,数字永远不会相同,所以我不知道如何称呼它们。 在浏览了此处的一些帖子后,我写了以下内容,但它仅适用于一个级别,而不适用于 JSON 中的下一个级别。
request = requests.get(getCyclesURL, headers=headers)
requestData = json.loads(request.text)
requestDataKeys = requestData.keys
for k in requestDataKeys():
dictionaryIDs = requestData[k]
for m in requestDataKeys:
newDictionaryIDs = requestData[k][m]
for dict in newDictionaryIDs:
if dict['versionName'] == versionName:
versionID = dict['versionID']
print '%s: %s'%(versionName, versionID)
看看惊人的boltons
图书馆! 它有一个重remap
功能,在您的情况下可能有点矫枉过正,但这是一件值得了解的好事情。 这是从嵌套数据结构中提取所有带有'name': 'Regression'
dicts 的优雅方法:
from boltons.iterutils import remap
# Copy your actual data here
data = {'14500': [{'5': {'name': 'Regression'}, '7': {'name': 'Ad hoc'}}]}
regressions = []
def visit(path, key, value):
if isinstance(value, dict) and value.get('name') == 'Regression':
# You can do whatever you want here!
# If you're here then `value` is a dict
# and its `name` field equals to 'Regression'.
regressions.append(value)
return key, value
remap(data, visit=visit, reraise_visit=False)
assert regressions == [{'name': 'Regression'}]
如果您只需要某个级别的字典,您还可以在visit
函数中检查path
长度。
def find_in_dicts(d, key, value): #This finds all dictionaries that has the given key and value
for k, v in d.items():
if k == key:
if v == value:
yield d
else:
if isinstance(v, dict):
for i in find_in_dicts(v, key, value):
yield i
elif isinstance(v, list) and isinstance(v[0], dict):
for item in v:
for i in find_in_dicts(item, key, value):
yield i
无论您的数据结构有多深,这都应该递归地工作。 我目前无法测试它,但我希望它最终能给你一些想法。
这是根据您的确切输入量身定制的部分脚本。 如果它找到name: regression
在适当的级别,它会打印一些相关的值。
for k, list_of_dicts in requestData.items():
for d in list_of_dicts:
for k, v in d.items():
if isinstance(v, dict) and v.get('name') == "Regression":
print '%s: %s %s'%(v.get('projectId'),
v.get('versionName'),
v.get('versionId'))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.