YAML字典键重排优化方案及问题命名咨询(Python优先)
嵌套字典结构重排优化及问题命名咨询
原始数据结构(YAML加载后字典)
song1: chunk1: attr1: value attr2: value attr3: value chunk2: attr1: value attr2: value attr3: value chunk3: attr1: value attr2: value attr3: value song2: chunk1: attr1: value # ... 以此类推
目标重排结构
attr1: song1: chunk1: value chunk2: value chunk3: value song2: chunk1: value chunk2: value chunk3: value song3: chunk1: value chunk2: value chunk3: value attr2: # ... 以此类推
现有基础实现
reordered = {} for song_name in output.keys(): for chunk_name in output[song_name].keys(): for attr_name in output[song_name][chunk_name].keys(): if attr_name not in reordered: reordered[attr_name] = {} if song_name not in reordered[attr_name]: reordered[attr_name][song_name] = {} reordered[attr_name][song_name][chunk_name] = output[song_name][chunk_name][attr_name]
需求
- 寻找非暴力的优化实现方法(优先Python结合YAML的方案,也欢迎通用思路)
- 了解这类问题的专业名称
解答
问题专业名称
这类多层嵌套结构的键层级反转/重新组织,属于数据转置(Data Transposition)的范畴,更具体可称为嵌套字典的层级转置。它本质是将原结构的维度顺序(歌曲→块→属性)转换为属性→歌曲→块,和表格转置的逻辑类似,只是扩展到了多层嵌套场景。
优化实现方法
方法1:使用collections.defaultdict简化代码
利用defaultdict自动创建嵌套字典,省去手动判断键是否存在的步骤,代码更简洁可读:
from collections import defaultdict import yaml def transpose_nested_dict(data): reordered = defaultdict(lambda: defaultdict(dict)) for song, chunks in data.items(): for chunk, attrs in chunks.items(): for attr, value in attrs.items(): reordered[attr][song][chunk] = value # 可选:转换为普通字典(若不需要defaultdict特性) return {k: dict(v) for k, v in reordered.items()} # 加载YAML并转置 with open("input.yaml", "r") as f: output = yaml.safe_load(f) result = transpose_nested_dict(output) # 保存为目标YAML结构 with open("output.yaml", "w") as f: yaml.dump(result, f, sort_keys=False)
方法2:递归通用转置(支持任意多层级)
如果后续结构层级可能变化,递归方法更通用,可处理任意深度的嵌套结构转置(需指定层级转换顺序):
from collections import defaultdict def recursive_transpose(data, level_order): if len(level_order) == 1: return data transposed = defaultdict(lambda: {}) for key, sub_data in data.items(): sub_transposed = recursive_transpose(sub_data, level_order[1:]) for sub_key, value in sub_transposed.items(): transposed[sub_key][key] = value return transposed # 示例:原层级顺序为 song→chunk→attr,目标为 attr→song→chunk,对应level_order=[2,0,1] result = recursive_transpose(output, [2,0,1])
方法3:固定层级字典推导式
若结构固定为3层,可使用嵌套字典推导式实现,代码更紧凑:
reordered = { attr: { song: {chunk: val for chunk, attrs in output[song].items() if attr in attrs} for song in output } for attr in set(attr for song in output for chunk in output[song] for attr in output[song][chunk]) }
说明
- YAML处理细节:使用
yaml.safe_load加载数据,yaml.dump时设置sort_keys=False可保留键的原始顺序(Python 3.7+字典本身具备有序性)。 - 性能对比:所有优化方法与原始代码时间复杂度均为O(N)(N为所有属性值的总数),但代码可读性和简洁性大幅提升,避免了重复的键存在性判断。
内容的提问来源于stack exchange,提问作者rithvik
相关产品推荐
相关产品推荐

