resueltos recorrer lista elementos ejercicios diccionarios diccionario dentro convertir anidados agregar python list dictionary

recorrer - lista de diccionarios python



Establecer un valor en un diccionario de python anidado dada una lista de índices y valores (5)

Algo como esto podría ayudar:

def nested_set(dic, keys, value): for key in keys[:-1]: dic = dic.setdefault(key, {}) dic[keys[-1]] = value

Y puedes usarlo así:

>>> d = {} >>> nested_set(d, [''person'', ''address'', ''city''], ''New York'') >>> d {''person'': {''address'': {''city'': ''New York''}}}

Lo siento si esta pregunta ha sido respondida antes. He estado buscando soluciones, pero tal vez no esté usando los términos de búsqueda correctos.

De todos modos, lo que estoy tratando de hacer es establecer mediante programación un valor en un diccionario, potencialmente anidado, dada una lista de índices y un valor.

Entonces, por ejemplo, digamos que mi lista de índices es:

[''person'', ''address'', ''city'']

y el valor es

''New York''

Quiero como resultado un objeto de diccionario como:

{ ''Person'': { ''address'': { ''city'': ''New York'' } }

Básicamente, la lista representa una ''ruta'' en un diccionario anidado.

Creo que puedo construir el diccionario en sí, pero donde estoy tropezando es cómo establecer el valor. Obviamente, si estuviera escribiendo código para esto manualmente sería:

dict[''Person''][''address''][''city''] = ''New York''

Pero, ¿cómo indizo en el diccionario y establezco el valor así programáticamente si solo tengo una lista de los índices y el valor?

Espero que esto tenga sentido y no sea una pregunta demasiado tonta ... :) Gracias por cualquier ayuda.


Aquí está mi solución simple: sólo escribe

terms = [''person'', ''address'', ''city''] result = nested_dict(3, str) result[terms] = ''New York'' # as easy as it can be

Incluso puedes hacer:

terms = [''John'', ''Tinkoff'', ''1094535332''] # account in Tinkoff Bank result = nested_dict(3, float) result[terms] += 2375.30

Ahora el backstage:

from collections import defaultdict class nesteddict(defaultdict): def __getitem__(self, key): if isinstance(key, list): d = self for i in key: d = defaultdict.__getitem__(d, i) return d else: return defaultdict.__getitem__(self, key) def __setitem__(self, key, value): if isinstance(key, list): d = self[key[:-1]] defaultdict.__setitem__(d, key[-1], value) else: defaultdict.__setitem__(self, key, value) def nested_dict(n, type): if n == 1: return nesteddict(type) else: return nesteddict(lambda: nested_dict(n-1, type))


Aquí hay otra opción:

from collections import defaultdict recursivedict = lambda: defaultdict(recursivedict) mydict = recursivedict()

Originalmente obtuve esto desde aquí: https://.com/a/10218517/1530754 .

Bastante inteligente y elegante si me preguntas.


En primer lugar, es probable que desee ver setdefault

Como una función lo escribiría como

def get_leaf_dict( dict, key_list): res=dict for key in key_list: res=dict.setdefault( key, {} ) return res

Esto sería utilizado como:

get_leaf_dict( dict, [''Person'', ''address'', ''city'']) = ''New York''

Esto podría solucionarse con el manejo de errores y, por lo tanto, también podría ser bueno usar *args lugar de un solo argumento de lista de claves; pero la idea es que puedes iterar sobre las teclas, obteniendo el diccionario apropiado en cada nivel.


Me tomé la libertad de extender el código de la respuesta de Bakuriu . Por lo tanto, los votos positivos sobre esto son opcionales, ya que su código es en sí mismo una solución ingeniosa, en la que no habría pensado.

def nested_set(dic, keys, value, create_missing=True): d = dic for key in keys[:-1]: if key in d: d = d[key] elif create_missing: d = d.setdefault(key, {}) else: return dic if keys[-1] in d or create_missing: d[keys[-1]] = value return dic

Al configurar create_missing en True, te aseguras de establecer solo los valores ya existentes:

# Trying to set a value of a nonexistent key DOES NOT create a new value print(nested_set({"A": {"B": 1}}, ["A", "8"], 2, False)) >>> {''A'': {''B'': 1}} # Trying to set a value of an existent key DOES create a new value print(nested_set({"A": {"B": 1}}, ["A", "8"], 2, True)) >>> {''A'': {''B'': 1, ''8'': 2}} # Set the value of an existing key print(nested_set({"A": {"B": 1}}, ["A", "B"], 2)) >>> {''A'': {''B'': 2}}