You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从深层遍历嵌套字典并按依赖逐层向上删除id的需求

问题描述

我有一个由报告生成的嵌套字典(结构可能变化),需要完成以下操作:

  • 从字典的最深层开始,找到其中的id字段(示例中如'id': u'ef3c8cf1-0987-4e56-a6d5-763c42be1f75',可能存在多个)
  • 删除该id后将剩余内容上移一层,重复此操作直至删除顶层id
  • 由于存在依赖关系,需先删除孤立的id,再逐层向上处理

字典示例

{ 
    'id': u'4c31d813-a989-47dd-b01b-9a27b8db2dfc', 
    'snapshots': [ 
        { 
            'id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5', 
            'volumes': [ 
                { 
                    'id': u'5488de90-50dc-4d72-a6aa-c995422fa179', 
                    'snapshots': [], 
                    'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5' 
                }, 
                { 
                    'id': u'e566645f-4fb3-4778-be67-447a5bdd678d', 
                    'snapshots': [ 
                        { 
                            'id': u'd637f6ea-4a41-448c-874f-ffe624ddc597', 
                            'volumes': [ 
                                { 
                                    'id': u'ef3c8cf1-0987-4e56-a6d5-763c42be1f75', 
                                    'snapshots': [], 
                                    'snapshot_id': u'd637f6ea-4a41-448c-874f-ffe624ddc597' 
                                } 
                            ] 
                        } 
                    ], 
                    'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5'
                }, 
                { 
                    'id': u'196483ee-4f21-4d83-8e15-8caea532b2ab', 
                    'snapshots': [], 
                    'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5' 
                } 
            ] 
        } 
    ], 
    'snapshot_id': None 
}

相关Python代码

oh=openstack_helper.OpenstackHelper()
def get_objects(item):
    items=None
    if item == 'stacks':
        items=oh.get_stacks()
    if item == 'volumes':
        items=oh.get_volumes()
    if item == 'snapshots':
        items=oh.get_snapshots()
    return items

def dep_graph(volumes,snapshots,snapshot_id=None):
    vol_list=[]
    for volume in volumes:
        if volume.snapshot_id == snapshot_id:
            info={'id':volume.id,'snapshot_id':volume.snapshot_id,'snapshots':[], }
            vol_list.append(info)
    for snapshot in snapshots:
        for volume in vol_list:
            snap_list=[]
            if snapshot.volume_id == volume['id']:
                info={'id':snapshot.id, 'volumes':[]}
                info['volumes'].extend(dep_graph(volumes,snapshots,snapshot.id))
                volume['snapshots'].append(info)
    return vol_list

if __name__ == '__main__':
    volumes = get_objects('volumes')
    snapshots = get_objects('snapshots')
    output = dep_graph(volumes, snapshots)
    print output
解决方案

要实现从最深层开始删id并把剩余内容上移的需求,咱们可以用**深度优先遍历(DFS)**的思路——先钻到最内层的节点处理完,再一步步往外走,这样刚好符合先删孤立id、再逐层向上处理的要求。

下面是具体的实现代码:

def remove_ids_recursive(data):
    # 如果是列表,递归处理每个元素
    if isinstance(data, list):
        return [remove_ids_recursive(item) for item in data]
    # 如果是字典,先递归处理所有值,再删除id并重组
    elif isinstance(data, dict):
        # 先处理所有子节点(深度优先,确保先处理最深层)
        processed_data = {k: remove_ids_recursive(v) for k, v in data.items()}
        # 删除id字段
        if 'id' in processed_data:
            del processed_data['id']
        return processed_data
    # 非字典非列表,直接返回
    else:
        return data

# 测试示例字典
sample_dict = { 
    'id': u'4c31d813-a989-47dd-b01b-9a27b8db2dfc', 
    'snapshots': [ 
        { 
            'id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5', 
            'volumes': [ 
                { 
                    'id': u'5488de90-50dc-4d72-a6aa-c995422fa179', 
                    'snapshots': [], 
                    'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5' 
                }, 
                { 
                    'id': u'e566645f-4fb3-4778-be67-447a5bdd678d', 
                    'snapshots': [ 
                        { 
                            'id': u'd637f6ea-4a41-448c-874f-ffe624ddc597', 
                            'volumes': [ 
                                { 
                                    'id': u'ef3c8cf1-0987-4e56-a6d5-763c42be1f75', 
                                    'snapshots': [], 
                                    'snapshot_id': u'd637f6ea-4a41-448c-874f-ffe624ddc597' 
                                } 
                            ] 
                        } 
                    ], 
                    'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5'
                }, 
                { 
                    'id': u'196483ee-4f21-4d83-8e15-8caea532b2ab', 
                    'snapshots': [], 
                    'snapshot_id': u'3ddc7ddd-02ca-4669-a0cb-fb0d56a4a6f5' 
                } 
            ] 
        } 
    ], 
    'snapshot_id': None 
}

# 处理后的结果
result = remove_ids_recursive(sample_dict)
print(result)

代码说明

  1. 深度优先遍历逻辑:函数会先递归处理所有子元素(比如列表里的每一项、字典里的每个值),确保最深层的节点最先被处理,完美契合先删孤立id的要求。
  2. 删除id并保留其他内容:等所有子节点都处理完后,再删掉当前字典里的id字段,剩下的键值对自然就相当于“上移”后的内容了。
  3. 适配可变结构:不管你的字典嵌套结构怎么变,只要是字典和列表组成的嵌套结构,这个函数都能正确处理。

你可以把这个函数集成到你的现有代码中,比如在dep_graph函数返回结果后,调用remove_ids_recursive(output)来得到最终处理后的结果。

内容的提问来源于stack exchange,提问作者Heenashree Khandelwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:06:46