resueltos recorrer lista elementos ejercicios diccionarios diccionario dentro convertir agregar python python-3.x list dictionary nested

recorrer - lista de diccionarios python



Conversión de listas de listas en un diccionario de diccionarios en Python (5)

Estoy intentando convertir una lista de estructura de datos de listas en un diccionario de diccionarios.

La lista se define de la siguiente manera:

l = [ [''PP'',''Ear-rings'', ''Holesovice'', 2000], [''PP'',''Skirts'', ''Holesovice'', 1000], [''PP'',''Dresses'', ''E-shop'', 1500], [''BM'',''Butterfly'', ''Holesovice'', 1600] ]

Mi objetivo es tener la estructura del diccionario de la siguiente manera:

#{''PP'' : {''Holesovice'' : {''Ear-rings'' : 2000, ''Skirts'' : 1000}, # ''E-shop'' : {''Dresses'' : 1500}}, # ''BM'' : {''Holesovice'' : {''Butterfly'' : 1600}} #}

Este bit de código no devuelve la salida deseada:

labels_d = {} items_d = {} shops_d = {} for index, row in enumerate(l): items_d[row[1]] = row[3] shops_d[row[2]] = items_d labels_d[row[0]] = shops_d print(labels_d)

Encontré algunas publicaciones que tratan sobre la conversión de listas a diccionarios here y here pero no hice que funcionara como quería. ¿Hay alguna forma "limpia" de cómo lograr la estructura publicada anteriormente?


Aquí publicamos una forma bastante sencilla de componer un nuevo diccionario:

Si los elementos en cada fila de la lista no están en la profundidad correspondiente del diccionario, simplemente agregue / agregue el par clave-valor al dict.

código:

list = [ [''PP'',''Ear-rings'', ''Holesovice'', 2000], [''PP'',''Skirts'', ''Holesovice'', 1000], [''PP'',''Dresses'', ''E-shop'', 1500], [''BM'',''Butterfly'', ''Holesovice'', 1600] ] dicta = {} for row in list: if row[0] not in dicta.keys(): dicta[row[0]] = {row[2]:{row[1]:row[3]}} continue if row[2] not in dicta[row[0]].keys(): dicta[row[0]][row[2]] = {row[1]:row[3]} continue if row[1] not in dicta[row[0]][row[2]].keys(): dicta[row[0]][row[2]][row[1]] = row[3] print(dicta)

salida:

{''BM'': {''Holesovice'': {''Butterfly'': 1600}}, ''PP'': {''E-shop'': {''Dresses'': 1500}, ''Holesovice'': {''Ear-rings'': 2000, ''Skirts'': 1000}}}


El uso de dict.setdefault(key, {}) es una buena manera de abordar la creación de diccionarios anidados de profundidad fija.

l = [ [''PP'',''Ear-rings'', ''Holesovice'', 2000], [''PP'',''Skirts'', ''Holesovice'', 1000], [''PP'',''Dresses'', ''E-shop'', 1500], [''BM'',''Butterfly'', ''Holesovice'', 1600] ] d = {} for tag, item, source, qty in l: d.setdefault(tag, {}).setdefault(source, {})[item] = qty

Salida

{''BM'': {''Holesovice'': {''Butterfly'': 1600}}, ''PP'': {''E-shop'': {''Dresses'': 1500}, ''Holesovice'': {''Ear-rings'': 2000, ''Skirts'': 1000}}}

Generalización

La solución anterior se puede hacer más general al construir una clase de diccionario anidado, eliminando los requisitos para tener una profundidad fija.

class NestedDict(dict): def __getitem__(self, item): if item not in self: self[item] = NestedDict() return super().__getitem__(item) d = NestedDict() for tag, item, source, qty in l: d[tag][source][item] = qty

También tenga en cuenta que el enfoque de clase se crea, por lo que solo crea un objeto si la clave no existe, mientras que el enfoque setdefault creó un dict vacío en cada acceso.


Puede utilizar collections.defaultdict y iterar. En este caso, puede definir con precisión un diccionario anidado para reflejar su estructura de datos.

from collections import defaultdict L = [[''PP'',''Ear-rings'', ''Holesovice'', 2000], [''PP'',''Skirts'', ''Holesovice'', 1000], [''PP'',''Dresses'', ''E-shop'', 1500], [''BM'',''Butterfly'', ''Holesovice'', 1600]] d = defaultdict(lambda: defaultdict(lambda: defaultdict(int))) for code, item, shop, value in L: d[code][shop][item] = value

Resultado

defaultdict({''BM'': defaultdict({''Holesovice'': defaultdict(int, {''Butterfly'': 1600})}), ''PP'': defaultdict({''E-shop'': defaultdict(int, {''Dresses'': 1500}), ''Holesovice'': defaultdict(int, {''Ear-rings'': 2000, ''Skirts'': 1000})})})


Puedes usar el truco defaultdict infinitamente anidado:

from collections import defaultdict def nested_dict(): return defaultdict(nested_dict) nd = nested_dict() for a, b, c, d in l: nd[a][c][b] = d


def toNested1(l): def addKeyDict(map,key): if key not in map: item = map[key] = {} return item return map[key] zz = {} for a0,a1,a2,a3 in l : addKeyDict( addKeyDict( zz, a0) , a2 )[a1] = a3 return zz