Создать вложенный словарь из плоского словаря - PullRequest
2 голосов
/ 25 марта 2019

У меня есть следующий словарь, в котором 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": []
        }
    }
}

1 Ответ

4 голосов
/ 25 марта 2019

Вы можете использовать рекурсию для создания вложенного словаря, а затем удалить ключи, у которых нет дочерних элементов:

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": []
     }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...