我正在寻找一种通用的方法来转换像这样的扁平字典:
{
"det_0_prod_di_0_field" : "value",
"det_0_prod_di_0_adi_0_field" : "value",
"det_0_prod_di_0_adi_1_field" : "value",
"det_1_prod_di_0_field" : "value",
"det_1_prod_di_0_adi_0_field" : "value",
"det_1_prod_di_0_adi_1_field" : "value",
}
进入这个:
[
{
"det" : {
"prod" : [{
"di" : {
"field" : "value",
"adi" : [{"field" : "value"}, {"field" : "value"}]
},
}]
},
"det" : {
"prod" : [{
"di" : {
"field" : "value",
"adi" : [{"field" : "value"}, {"field" : "value"}]
},
}]
}
}
]
请注意,我必须为"重复" ...的项目创建dict列表。此外,它必须是通用的,因为它可以有很多"嵌套级别"。 ..每次" _0"," _1"等等出现在一个键中,应该创建一个列表...
谢谢!
答案 0 :(得分:2)
第一步显然是将每个键分成几个部分:
target = {}
for key, value in source.items():
components = key.split('_')
现在,您如何处理这些组件?从左到右走每一个,跟踪当前集合以及下一个集合的索引或关键字,在此过程中创建任何缺少的子集合。
你还没有指定你的规则是什么算作索引与键,如果索引被跳过或出现乱序会发生什么情况,如果你在同一个前缀下得到一个索引和一个键会发生什么等等,所以我只是为每一个选择一些任意规则 - 只需将每个组件视为一个键,因为这样可以获得最短的代码。这显然不是你想要的规则,但如果你了解代码,你应该能够适当地调整它;如果没有,您需要在尝试使用之前了解它。
subtarget = target
for component in components[:-1]:
subtarget = subtarget.setdefault(component, dict())
subtarget[components[-1]] = value
如果您了解代码但不知道如何调整代码,则可能需要查找int
函数,try
语句或list.insert
方法
答案 1 :(得分:1)
您可以考虑遵循并使用formencode的方法将结构序列化为扁平名称,然后再将其读回。
http://www.formencode.org/en/latest/modules/variabledecode.html#module-formencode.variabledecode