我正在尝试从JSON数组中提取许多值,因此我要遍历它以根据其键提取值,但是其中一个键会根据项目而变化,并且在遇到循环时会收到KeyError不同的密钥。
我尝试使用try和except来捕获此错误,但是由于我遍历整个数组,这次它将为另一个键抛出相同的异常。
这是我提取值的代码:
df = []
for item in json_response["items"]:
df.append({
'AccountName': item["accountName"],
'Action': item["action"],
'Application': item["application"],
'AppID': item["attributes"]["appId"],
'AppName': item["attributes"]["AppName"],
'Errors': item["attributes"]["errors"],
'ContextID': item["contextid"],
'Created': item["created"],
'HostName': item["hostname"],
'EventID': item["id"],
'Info': item["info"],
'ipaddr': item["ipaddr"],
'EventSource': item["source"],
'Stack': item["stack"],
'Target': item["target"],
'TrackingID': item["trackingId"],
'Type': item["type"]
})
这是我从中提取的更大数组中的示例JSON:
{
"accountName": null,
"action": "Disable",
"application": "Application1",
"attributes": {
"appId": "7d264050024",
"AppName": "Application1",
"errors": [
"Rule: Rule not found."
]
},
"contextid": null,
"created": 1553194821098,
"hostname": null,
"id": "ac09ea0082",
"info": null,
"ipaddr": null,
"source": "System1",
"stack": null,
"target": "TargetName1.",
"trackingId": null,
"type": null
}
这可以工作,但有时“属性”如下所示:
"attributes": {
"appId": "7d2451684288",
"cloudAppName": "Application1",
"RefreshFailure": true
}
遍历整个数组时如何提取“错误”值或“ RefreshFailure”值?
答案 0 :(得分:3)
测试属性中键的存在以检索不同的值:
df = []
for item in json_response["items"]:
errors = "NA"
if "errors" in item["attributes"]
errors = item["attributes"]["errors"]
elif "RefreshFailure" in item["attributes"]:
errors = item["attributes"]["RefreshFailure"]
df.append({
'AccountName': item["accountName"],
'Action': item["action"],
'Application': item["application"],
'AppID': item["attributes"]["appId"],
'AppName': item["attributes"]["AppName"],
'Errors': errors,
'ContextID': item["contextid"],
'Created': item["created"],
'HostName': item["hostname"],
'EventID': item["id"],
'Info': item["info"],
'ipaddr': item["ipaddr"],
'EventSource': item["source"],
'Stack': item["stack"],
'Target': item["target"],
'TrackingID': item["trackingId"],
'Type': item["type"]
})
答案 1 :(得分:0)
我试图模拟您的数据以使代码正常工作。
import json
from pprint import pprint
json_data = '''
{
"items": [
{
"accountName": null,
"action": "Disable",
"application": "Application1",
"attributes": {
"appId": "7d264050024",
"AppName": "Application1",
"errors": [
"Rule: Rule not found."
]
},
"contextid": null,
"created": 1553194821098,
"hostname": null,
"id": "ac09ea0082",
"info": null,
"ipaddr": null,
"source": "System1",
"stack": null,
"target": "TargetName1.",
"trackingId": null,
"type": null
},
{
"accountName": null,
"action": "Disable",
"application": "Application1",
"attributes": {
"appId": "7d2451684288",
"cloudAppName": "Application1",
"RefreshFailure": true
},
"contextid": null,
"created": 1553194821098,
"hostname": null,
"id": "ac09ea0082",
"info": null,
"ipaddr": null,
"source": "System1",
"stack": null,
"target": "TargetName1.",
"trackingId": null,
"type": null
}
]
}'''
json_response = json.loads(json_data)
def capitalize(s):
return s[0].upper() + s[1:]
df = []
for item in json_response["items"]:
d = {}
# Iterate over the items in the dictionary/json object and add them one by one using a loop
# This will work even if the items in the json_response changes without having to change the code
for key, value in item.items():
# "attributes" is itself a dictionary/json object
# Its items have to be unpacked and added instead of adding it as a raw object
if isinstance(value, dict):
for k, v in value.items():
d[capitalize(k)] = v
else:
d[capitalize(key)] = value
df.append(d)
pprint(df)
输出:
[{'AccountName': None,
'Action': 'Disable',
'AppId': '7d264050024',
'AppName': 'Application1',
'Application': 'Application1',
'Contextid': None,
'Created': 1553194821098,
'Errors': ['Rule: Rule not found.'],
'Hostname': None,
'Id': 'ac09ea0082',
'Info': None,
'Ipaddr': None,
'Source': 'System1',
'Stack': None,
'Target': 'TargetName1.',
'TrackingId': None,
'Type': None},
{'AccountName': None,
'Action': 'Disable',
'AppId': '7d2451684288',
'Application': 'Application1',
'CloudAppName': 'Application1',
'Contextid': None,
'Created': 1553194821098,
'Hostname': None,
'Id': 'ac09ea0082',
'Info': None,
'Ipaddr': None,
'RefreshFailure': True,
'Source': 'System1',
'Stack': None,
'Target': 'TargetName1.',
'TrackingId': None,
'Type': None}]
如果即使实际密钥名称为Errors
,也希望密钥名称为RefreshFailure
,则可以在df.append(d)
之前添加以下代码行
...
if 'RefreshFailure' in d:
d['Errors'] = d['RefreshFailure']
del d['RefreshFailure']
df.append(d)
使用这些额外的几行代码,输出将如下所示:
[{'AccountName': None,
'Action': 'Disable',
'AppId': '7d264050024',
'AppName': 'Application1',
'Application': 'Application1',
'Contextid': None,
'Created': 1553194821098,
'Errors': ['Rule: Rule not found.'],
'Hostname': None,
'Id': 'ac09ea0082',
'Info': None,
'Ipaddr': None,
'Source': 'System1',
'Stack': None,
'Target': 'TargetName1.',
'TrackingId': None,
'Type': None},
{'AccountName': None,
'Action': 'Disable',
'AppId': '7d2451684288',
'Application': 'Application1',
'CloudAppName': 'Application1',
'Contextid': None,
'Created': 1553194821098,
'Errors': True,
'Hostname': None,
'Id': 'ac09ea0082',
'Info': None,
'Ipaddr': None,
'Source': 'System1',
'Stack': None,
'Target': 'TargetName1.',
'TrackingId': None,
'Type': None}]