【问题标题】:Create Nested Dictionary From Flat Dictionary从平面词典创建嵌套词典
【发布时间】:2019-08-15 05:00:51
【问题描述】:

我有以下字典,其中keys 是父类,values 是从它们继承的子类列表。

{
    "Animal": 
        ["Dog"]
    ,  
    "Dog": 
        ["Labrador"]
    , 
    "Vehicle": 
        ["PetrolCar", 
        "DieselCar"]
    ,
    "DieselCar": 
        ["Hyundai"]
    , 
    "PetrolCar": 
        ["Hyundai", 
        "Ford"]
}

如您所见,一些父类也是另一个父类的子类(深度继承),即Animal -> Dog -> Labrador

我怎样才能格式化它,以便输出代表继承的级别,如下所示:

{
    "Animal": {
        "Dog": { 
            "Labrador": []
        }
    }, 
    "Vehicle": {
        "PetrolCar": {
            "Hyundai": [], 
            "Ford": []
        },
        "DieselCar": { 
            "Hyundai": []
        }
    }
}

我还希望能够通过添加更多父母或孩子来扩展提供的数据集。例如:将ElectricCar 添加为Vehicle 的子代,将Tesla 添加为ElectricCar 的子代。并将Cat 添加为Animal 的子代,没有它自己的子代。

输入:

{
    "Animal": 
        ["Dog",
        "Cat"]
    ,  
    "Dog": 
        ["Labrador"]
    , 
    "Vehicle": 
        ["PetrolCar", 
        "DieselCar",
        "ElectricCar"]
    ,
    "DieselCar": 
        ["Hyundai"]
    , 
    "PetrolCar": 
        ["Hyundai", 
        "Ford"]
    ,
    "ElectricCar": 
        ["Tesla"]
}

输出:

{
    "Animal": {
        "Dog": { 
            "Labrador": []
        },
        "Cat": []
    }, 
    "Vehicle": {
        "PetrolCar": {
            "Hyundai": [], 
            "Ford": []
        },
        "DieselCar": { 
            "Hyundai": []
        },
        "ElectricCar": { 
            "Tesla": []
        }
    }
}

【问题讨论】:

  • 你可以从你的初始字典构建一个图表,然后通过孩子们的方式进行 DFS,以这种方式构建最终的字典

标签: python python-2.7 dictionary nested


【解决方案1】:

您可以使用递归来生成嵌套字典,然后删除没有任何子项的键:

data = {'Animal': ['Dog', 'Cat'], 'Dog': ['Labrador'], 'Vehicle': ['PetrolCar', 'DieselCar', 'ElectricCar'], 'DieselCar': ['Hyundai'], 'PetrolCar': ['Hyundai', 'Ford'], 'ElectricCar': ['Tesla']}
def build(key):
  return {i:[] if i not in data else build(i) for i in data[key]}

results = {i:build(i) for i in data}

import json
print(json.dumps({a:b for a, b in results.items() if any(h for h in b.values())}, indent=4))

输出:

{
  "Animal": {
    "Dog": {
        "Labrador": []
    },
    "Cat": []
  },
  "Vehicle": {
    "PetrolCar": {
        "Hyundai": [],
        "Ford": []
     },
     "DieselCar": {
        "Hyundai": []
     },
     "ElectricCar": {
        "Tesla": []
     }
   }
}

【讨论】:

  • 谢谢!你能解释一下这是如何工作的吗?它适用于提供的示例,但是当我添加 Vehicle 的另一个孩子时失败,所以我想调整您的代码,使其适用于任何提供的数据集
  • @Gary 你能发布带有Vehicle 的附加子节点的数据以及你想要的输出吗?目前,如果原始数据中不存在子值,则因为是list的一个元素,而list是父键的值。但是,如果一个键的某些值存在于数据中,而某些值不存在,那么应该如何表示?
  • @Gary 谢谢。 "ElectricCar" 未包含在最终输出中的原因是因为"ElectricCar" 不会出现在"Vehicle" 的孩子中,因此在build 的循环中不会访问它。但是,如果将"ElectricCar" 添加到"Vehicle" 下的列表中,则会生成所需的输出。请查看我最近的编辑,因为我已经发布了这个结果。
  • 是的,很抱歉您的原始代码按预期工作。还有一个查询 - 我怎样才能使树的所有元素都有一个子列表,如果孩子没有任何孩子,则该列表可以为空?我将把它添加到原始帖子中。
  • @Gary 也更新以反映添加了Cat
猜你喜欢
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多