在python中从平面字典创建嵌套字典的通用方法

时间:2014-10-06 22:49:26

标签: python dictionary

我正在寻找一种通用的方法来转换像这样的扁平字典:

{
    "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"等等出现在一个键中,应该创建一个列表...

谢谢!

2 个答案:

答案 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