2
votes

Accéder au dictionnaire imbriqué via une variable

J'ai la configuration suivante: une fonction renvoie un dictionnaire avec N chronologies de taille égale (100k points). Le dictionnaire retourne ressemble à:

T = ("Name1", "Name2", "b") 
# Will allow me to access the timeline:
timelines["Name1"]["Name2"]["b"]
# by doing:
timelines[T[0]][T[1]][T[2]]

Comme vous l'avez peut-être compris, les timelines (liste de points) ne sont pas toujours stockées au même niveau. Parfois, je peux y accéder avec 1 clé, parfois avec 2, parfois avec 5. Ces clés me donneront les étiquettes de l'intrigue et sont nécessaires. Mon plan était de passer à la fonction plot un tuple des clés.

Exemple:

timelines = dict()
timelines["Name1"] = dict()
timelines["Name1"]["Name2"] = dict()
timelines["Name1"]["Name3"] = dict()
timelines["Name1"]["Name2"]["a"] = # List of 100k points
timelines["Name1"]["Name2"]["b"] = # List of 100k points
timelines["Name1"]["Name2"]["c"] = # List of 100k points
timelines["Name1"]["Name3"]["b"] = # List of 100k points
timelines["Name1"]["Name2"]["c"] = # List of 100k points
timelines["Name1"]["a"] = # List of 100k points
timelines["Name1"]["b"] = # List of 100k points
timelines["Name2"] # and so on.

Dans l'exemple ci-dessus, j'ai écrit moi-même le chemin du dictionnaire ( [T [0]] [T [1] ] [T [2]] ), mais comment puis-je accéder à la bonne chronologie avec un tuple T de taille inconnue? Comment puis-je décompresser le tuple dans un chemin de dictionnaire?

Merci :)


1 commentaires

Si vous accédez à votre dict plusieurs fois, il peut être avantageux de l'aplatir et de compresser les touches pour avoir un accès plus facile plus tard. En savoir plus sur ici et ici .


4 Réponses :


2
votes

Vous pouvez utiliser réduire

from functools import reduce

timelines = dict()
timelines["Name1"] = dict()
timelines["Name1"]["Name2"] = dict()
timelines["Name1"]["Name2"]["b"] = 'my data'

T = ("Name1", "Name2", "b") 

data = reduce(lambda d, key: d[key], T, timelines)

print(data)
# my data


2 commentaires

Fonctionne très bien. Pouvez-vous expliquer un peu ce qu'il fait? Je ne reçois pas cette déclaration lambda.


c'est une meilleure approche pour faire reduction (getitem, [list_of_keys], input_dict)



1
votes

vous pouvez utiliser une approche récursive

def access_my_dict(my_dict, tuple_keys):
    value = my_dict[tuple_keys[0]]
    if isinstance(value, dict):
        return access_my_dict(value, tuple_keys[0:])
    return value


0 commentaires

1
votes

Parcourez la structure de données comme ceci:

[12, 67, 45]

Sortie:

timelines = dict()
timelines["Name1"] = dict()
timelines["Name2"] = dict()
timelines["Name1"]["Name2"] = dict()
timelines["Name1"]["Name3"] = dict()
timelines["Name1"]["Name2"]["a"] = []  # List of 100k points
timelines["Name1"]["Name2"]["b"] = [12, 67, 45]  # List of 100k points
timelines["Name1"]["Name2"]["c"] = [12, 45]  # List of 100k points
timelines["Name1"]["Name3"]["b"] = []  # List of 100k points
timelines["Name1"]["Name2"]["c"] = []  # List of 100k points
timelines["Name1"]["a"] = []  # List of 100k points
timelines["Name1"]["b"] = []  # List of 100k points
timelines["Name2"]["Name23"] = dict()
timelines["Name2"]["Name23"]["Z"] = []  # and so on.


def get_time_line(path):
    data = timelines
    for path_element in path:
        data = data[path_element]
    return data

path = ("Name1", "Name2", "b")
print(get_time_line(path))


0 commentaires

5
votes

Je le ferais en fait comme ça, ce sera la méthode la plus rapide plus que probablement les appels

from functools import reduce
from operator import getitem

path = ['Name1', 'Name2', 'a']

reduce(getitem, path, dictionary)

Lambda peuvent devenir coûteux, d'autant plus que les mentionner getitem sera plus rapide que toute autre méthode répertoriée ici car elle est implémentée uniquement en C


0 commentaires