La conversión de una lista anidada de diccionario en Python

Él Yehui:

Me gustaría convertir una lista anidada de diccionario en una subestructura. Y encontrar una manera robusta para hacerlo. La estructura:

nested_list = [
  {
     "id" : "fruit",
     "name" : "apple"
  },
  {
     "name": "fruit"
  },
  {
     "id" : "fruit",
     "name" : "grape"
  },
  {
     "id" : "fruit",
     "name" : "pineapple"
  },
  {
     "name": "vehicle"
  },
  {
    "id" : "vehicle",
     "name": "car"
  },
  {
    "id" : "car",
     "name": "sedan"
  },
] 

Dentro:

{
  "vehicle": {
    "car": {
        "sedan" : {}
     }
  },
  "fruit" : {
     "apple": {},
    "grape": {},
    "pineapple": {}
  }
}

Tenga en cuenta que en este caso se puede ir dos abajo nivel. Pero puede ir de tres en el fondo también. Por ejemplo, una entrada adicional:

{ 
   "id" : "sedan", 
   "name": "mini sedan" 
}

Mi enfoque hasta ahora es:

for category in nested_list:
    if 'id' not in category:
        d[category['name']] = {}

for category in nested_list:
    if 'id' in category and category['id'] in d:
        d[category['id']][category['name']] = {}
    elif 'id' in category and category['id'] not in d:
        for k, v in d.items():
            if category['id'] in v:
                d[k][category['id']] = {category['name']: {}}
    # If there are not top level key then do nothing
    else:
        pass

Funciona en este caso. El problema es que no es lo suficientemente robusta. Estoy pensando en la recursividad, pero incapaz de descifrarlo. ¿Puede alguien ayudarme? Gracias

Boseong Choi:

Solución

Puede utilizar collections.defaultdicty dict.setdefault:

from collections import defaultdict

nested_list = [
    {
        "id": "fruit",
        "name": "apple"
    },
    {
        "name": "fruit"
    },
    {
        "id": "fruit",
        "name": "grape"
    },
    {
        "id": "fruit",
        "name": "pineapple"
    },
    {
        "name": "vehicle"
    },
    {
        "id": "vehicle",
        "name": "car"
    },
    {
        "id": "car",
        "name": "sedan"
    },
    {
        "id": "sedan",
        "name": "mini sedan"
    },
]

working_dict = defaultdict(dict)
result_dict = {}

for item in nested_list:
    name = item['name']
    if 'id' in item:
        id_ = item['id']
        working_dict[id_].setdefault(name, working_dict[name])
    else:
        result_dict[name] = working_dict[name]
print(working_dict)
print(result_dict)

salida:

defaultdict(<class 'dict'>, {'fruit': {'apple': {}, 'grape': {}, 'pineapple': {}}, 'apple': {}, 'grape': {}, 'pineapple': {}, 'vehicle': {'car': {'sedan': {'mini sedan': {}}}}, 'car': {'sedan': {'mini sedan': {}}}, 'sedan': {'mini sedan': {}}, 'mini sedan': {}})
{'fruit': {'apple': {}, 'grape': {}, 'pineapple': {}}, 'vehicle': {'car': {'sedan': {'mini sedan': {}}}}}

Explicación

  • La idea: dictes mutable.
  • working_dictes la tabla de referencia para todos los "id"s.
  • Si no existe tal identificación, regístrese {}para ello.
  • Y registrar los elementos sin idcampo, como elementos raíz en result_dict.

Adjuntar

Si no desea utilizar collections.defaultdict, sólo se puede utilizar dict.setdefault. Pero es más prolija.

working_dict = {}
result_dict = {}

for item in nested_list:
    name = item['name']
    if 'id' in item:
        id_ = item['id']
        working_dict.setdefault(id_, {}).setdefault(name, working_dict.setdefault(name, {}))
    else:
        result_dict[name] = working_dict.setdefault(name, {})
print(result_dict)

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=387482&siteId=1
Recomendado
Clasificación