Python:如何移除API返回JSON嵌套结构内的指定Key?
问题描述
调用API获取JSON格式数据后,需要移除其中特定的Key。目前用pop('id', None)成功移除外层字典的id、location等Key,但嵌套结构里的对应Key处理不了——比如items下每个元素的rules列表中每个字典的id,以及rules内policy字典的id。已经用嵌套循环实现需求,但想找更简洁高效的实现方式。
当前实现代码:
check = requests.get(standard_url+api_version+"/nfs-export-policies", headers=auth_headers, verify=False) centry = check.json()['items'] for item in centry: item.pop('id', None) item.pop('location', None)
API返回的原始JSON数据:
{'continuation_token': None, 'total_item_count': 1, 'items': [{'name': 'no_squash', 'id': 'e399c67e-595a-8b21-18dc-678164e360bd', 'enabled': True, 'is_local': True, 'location': {'name': 'fbstaines03', 'id': 'a7c7d4ad-b515-4f6b-a396-562cdad2063d', 'resource_type': 'arrays'}, 'version': 'ffffffff-d747-c55b-0000-0000411034c5', 'rules': [{'name': 'no_squash.1', 'id': '6680ab71-1823-48fc-bc84-920059d218c5', 'policy': {'name': 'no_squash', 'id': 'e399c67e-595a-8b21-18dc-678164e360bd', 'resource_type': 'nfs-export-policies'}, 'access': 'no-squash', 'anongid': None, 'anonuid': None, 'atime': True, 'client': '*', 'fileid_32bit': False, 'index': 1, 'permission': 'rw', 'secure': False, 'security': ['krb5', 'krb5i', 'krb5p', 'sys'], 'policy_version': 'ffffffff-d747-c55b-0000-0000411034c5'}], 'policy_type': 'nfs-export'}]}
优化实现方案
方法一:递归遍历处理(通用高效)
写一个递归函数,自动遍历所有嵌套的字典和列表,移除指定的Key。这种方式不管嵌套层级多深都能处理,代码复用性强。
示例代码:
def remove_keys(data, keys_to_remove): if isinstance(data, dict): # 处理当前字典的目标Key for key in keys_to_remove: data.pop(key, None) # 递归处理字典内的所有值 for value in data.values(): remove_keys(value, keys_to_remove) elif isinstance(data, list): # 递归处理列表内的每个元素 for item in data: remove_keys(item, keys_to_remove) return data # 使用示例 check = requests.get(standard_url+api_version+"/nfs-export-policies", headers=auth_headers, verify=False) response_data = check.json() # 指定需要移除的Key列表 target_keys = ['id', 'location'] # 处理整个响应数据(覆盖所有嵌套层级) processed_data = remove_keys(response_data, target_keys) centry = processed_data['items']
方法二:迭代式遍历(避免递归深度问题)
如果JSON嵌套极深(超过Python默认递归深度限制),可以用迭代方式遍历所有元素,通过栈结构处理:
def remove_keys_iterative(data, keys_to_remove): stack = [data] while stack: current = stack.pop() if isinstance(current, dict): for key in keys_to_remove: current.pop(key, None) # 将字典的所有值加入栈继续处理 stack.extend(current.values()) elif isinstance(current, list): # 将列表的所有元素加入栈继续处理 stack.extend(current) return data # 使用方式和递归版一致 check = requests.get(standard_url+api_version+"/nfs-export-policies", headers=auth_headers, verify=False) response_data = check.json() processed_data = remove_keys_iterative(response_data, ['id', 'location']) centry = processed_data['items']
方法三:固定结构的简化嵌套循环(直观可控)
如果你的JSON结构固定,不想写通用函数,也可以用更清晰的嵌套循环覆盖所有需要处理的层级:
check = requests.get(standard_url+api_version+"/nfs-export-policies", headers=auth_headers, verify=False) centry = check.json()['items'] for item in centry: # 处理item本身的Key item.pop('id', None) item.pop('location', None) # 处理rules列表中的元素 if 'rules' in item: for rule in item['rules']: rule.pop('id', None) # 处理rule内的policy字典 if 'policy' in rule: rule['policy'].pop('id', None)
方案对比
- 递归/迭代通用方法:适合结构不固定、嵌套层级多变的场景,一次编写可复用在多种JSON处理需求上。
- 简化嵌套循环:适合结构固定的场景,代码直观易懂,但扩展性差,JSON结构变化时需要同步修改代码。
内容的提问来源于stack exchange,提问作者Darren Miller
相关产品推荐
相关产品推荐

