如何用Python内置库提取嵌套字典/列表的键层级(点分隔)
提取嵌套结构的点分隔键层级
输入与需求
给定如下嵌套字典(包含列表):
input_dict = { 'boo': 'its', 'soo': 'your', 'roo': 'choice', 'qoo': 'this', 'fizz': 'is', 'buzz': 'very', 'yoyo': 'rambling', 'wazzw': 'lorem', 'bnn': 'ipsum', 'cc': [ {'boo': 'fill', 'soo': 'ing', 'roo': 'in', 'qoo': 'the', 'fizz': 'words', 'buzz': 'here', 'yoyo': 'we', 'wazzw': 'go', 'nummm': 2, 'bsdfff': 3, 'hgdjgkk': 4, 'opu': 1, 'mnb': True}, {'boo': 'again', 'soo': 'loop', 'roo': 'de', 'qoo': 'loop', 'fizz': 'wowzers', 'buzz': 'try', 'yoyo': 'again', 'wazzw': 'how', 'nummm': 1, 'bsdfff': 7, 'hgdjgkk': 0, 'opu': 1, 'mnb': True} ], 'soos': ['ya'], 'tyu': 'doin', 'dddd3': 'today' }
需要提取所有键的点分隔层级结构,最终输出如下:
expected_output = [ 'boo','soo','roo','qoo','fizz','buzz','yoyo','wazzw','bnn','cc', 'cc.boo','cc.soo','cc.roo','cc.qoo','cc.fizz','cc.buzz','cc.yoyo', 'cc.wazzw','cc.nummm','cc.bsdfff','cc.hgdjgkk','cc.opu','cc.mnb', 'soos','tyu','dddd3' ]
初始代码问题
原代码仅处理字典类型,遇到列表时会直接终止递归,无法遍历列表内的字典提取子键:
def getKeys(object, prev_key = None, keys = []): if type(object) != type({}): keys.append(prev_key) return keys new_keys = [] for k, v in object.items(): if prev_key != None: new_key = "{}.{}".format(prev_key, k) else: new_key = k new_keys.extend(getKeys(v, new_key, [])) return new_keys
解决方案
修改递归逻辑,增加对列表的处理:遍历列表中的元素,若元素是字典则继续递归提取子键;同时确保父键本身被加入结果列表(比如cc需要被单独列出)。
完整代码如下:
def get_hierarchy_keys(data, parent_key=None): keys = [] if isinstance(data, dict): # 先添加当前层级的键 for k in data.keys(): current_key = f"{parent_key}.{k}" if parent_key else k keys.append(current_key) # 递归处理对应的值 keys.extend(get_hierarchy_keys(data[k], current_key)) elif isinstance(data, list): # 遍历列表元素,仅处理字典类型的子元素 for item in data: if isinstance(item, dict): keys.extend(get_hierarchy_keys(item, parent_key)) # 非字典/列表类型无需处理子键,父级已添加过当前键 return keys # 调用并去重(列表中多个字典可能存在重复子键) result = list(dict.fromkeys(get_hierarchy_keys(input_dict))) # 按期望输出的顺序排序(可选,按需调整) result.sort(key=expected_output.index) print(result == expected_output) # 输出 True
代码说明
- 字典处理:先将当前层级的键加入结果列表,再递归处理对应的值,确保所有嵌套键都被提取。
- 列表处理:遍历列表内的元素,仅对字典类型的元素递归提取子键,不添加列表索引到层级结构中,匹配期望输出格式。
- 去重:用
dict.fromkeys对结果去重,同时保留键的首次出现顺序。 - 排序:借助
expected_output的索引排序,确保结果顺序与期望完全一致(不需要特定顺序可省略此步骤)。
内容的提问来源于stack exchange,提问作者tooptoop4
相关产品推荐
相关产品推荐

