如何从嵌套字典中获取非必存在的'action'键对应值?
问题解决:从嵌套字典中安全获取非必存键的值
你需要遍历query_res['hits']['hits']列表中的每个元素,安全提取event字典里的action值——因为该键并非所有元素都存在,直接访问会触发KeyError,而你之前的代码要么只处理第一个元素,要么未做异常/存在性判断。
你的代码问题分析
- 第一个循环
for q in query_res是遍历外层字典的键(比如took、hits等),而非目标列表hits,且每次仅检查第一个列表元素,导致输出重复且未遍历所有数据。 - 列表推导式
[a['_source']['event']['action'] for a in action]未做键存在性判断,遇到无action的元素会直接报错。
可行解决方案
方案1:使用dict.get()方法(推荐)
get()方法允许指定键不存在时的默认值,避免报错:
def events_query(): query_res = { 'took': 52, 'timed_out': False, '_shards': { 'total': 3, 'successful': 3, 'skipped': 1, 'failed': 0 }, 'hits': { 'total': {'value': 10000, 'relation': 'gte'}, 'max_score': None, 'hits': [ { '_index': 'winlogbeat-dc-2023.01.16-000195', '_type': '_doc', '_id': '_LrxCYYBiABa0UinUkYt', '_score': None, '_source': { 'agent': {'hostname': 'SRVDCMI'}, 'event': { 'code': '7036', 'provider': 'Service Control Manager', 'created': '2023-01-31T22:27:34.585Z', 'kind': 'event' } }, 'sort': [-9223372036854775808] }, { '_index': 'winlogbeat-dc-2023.01.16-000195', '_type': '_doc', '_id': '_brxCYYBiABa0UinUkYt', '_score': None, '_source': { 'agent': {'hostname': 'SRVDCMI'}, 'event': { 'code': '7036', 'provider': 'Service Control Manager', 'kind': 'event', 'created': '2023-01-31T22:27:34.585Z' } }, 'sort': [-9223372036854775808] }, { '_index': 'winlogbeat-dc-2023.01.16-000195', '_type': '_doc', '_id': '_rrxCYYBiABa0UinUkYt', '_score': None, '_source': { 'agent': {'hostname': 'SRVDCMI'}, 'event': { 'code': '7036', 'provider': 'Service Control Manager', 'kind': 'event', 'created': '2023-01-31T22:27:34.585Z' } }, 'sort': [-9223372036854775808] }, { '_index': 'winlogbeat-dc-2023.01.16-000195', '_type': '_doc', '_id': '_7rxCYYBiABa0UinUkZI', '_score': None, '_source': { 'agent': {'hostname': 'SRVDC01'}, 'event': { 'code': '4624', 'provider': 'Microsoft-Windows-Security-Auditing', 'created': '2023-01-31T22:27:34.622Z', 'kind': 'event', 'module': 'security', 'action': 'logged-in', 'category': ['authentication'], 'type': ['start'], 'outcome': 'success' } }, 'sort': [-9223372036854775808] }, { '_index': 'winlogbeat-dc-2023.01.16-000195', '_type': '_doc', '_id': 'ALrxCYYBiABa0UinUkdI', '_score': None, '_source': { 'agent': {'hostname': 'SRVDC01'}, 'event': { 'code': '4776', 'provider': 'Microsoft-Windows-Security-Auditing', 'created': '2023-01-31T22:27:34.622Z', 'kind': 'event', 'module': 'security', 'action': 'credential-validated', 'category': ['authentication'], 'type': ['start'], 'outcome': 'success' } }, 'sort': [-9223372036854775808] }]}} hits_list = query_res['hits']['hits'] # 提取action,不存在则返回'not found' action_list = [hit['_source']['event'].get('action', 'not found') for hit in hits_list] print(action_list) events_query()
方案2:显式判断键是否存在
通过in关键字检查action是否在event字典中:
def events_query(): query_res = { # 你的原始字典内容,同上 } hits_list = query_res['hits']['hits'] action_list = [] for hit in hits_list: event_dict = hit['_source']['event'] if 'action' in event_dict: action_list.append(event_dict['action']) else: action_list.append('not found') print(action_list) events_query()
方案3:异常捕获处理
用try-except捕获KeyError,适合复杂嵌套场景:
def events_query(): query_res = { # 你的原始字典内容,同上 } hits_list = query_res['hits']['hits'] action_list = [] for hit in hits_list: try: action = hit['_source']['event']['action'] action_list.append(action) except KeyError: action_list.append('not found') print(action_list) events_query()
以上三种方法都能遍历所有元素,安全获取action值,不会报错,且能收集所有结果。
内容的提问来源于stack exchange,提问作者Robin Sage
相关产品推荐
相关产品推荐

