Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access nested dictionary through a variable

I have the following setup: a function returns a dictionary with N timelines of equal size (100k points). The dictionary returns looks like:

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.

As you might have understood, the timelines (list of points) are not always stored in the same level. Sometimes I can access it with 1 key, sometimes with 2, sometimes with 5. Those keys will give me the labels for the plot and are necessary. My plan was to pass to the plot function a tuple of the keys.

Example:

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

In the example above, I wrote the dictionary path myself ([T[0]][T[1]][T[2]]), however how can I acess the right timeline with a tuple T of unknown size? How can I unpack the tuple into a dictionary path?

Thanks :)

like image 578
Mathieu Avatar asked Oct 15 '25 16:10

Mathieu


2 Answers

I would actually do it like this, this will be the fastest method more than likely

from functools import reduce
from operator import getitem

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

reduce(getitem, path, dictionary)

Lambda calls can become expensive especially as data grows, not to mention getitem will be faster than any other method listed here because it's implemented purely in C

like image 113
gold_cy Avatar answered Oct 18 '25 06:10

gold_cy


You could use reduce

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

The initial value is your timeline dict. Reduce iterates on your T tuple, and at each iteration, calls the lambda function. The lambda takes two arguments: the first one is the accumulated value, in this case the current dict d, and the second one is the key it got from the tuple during this iteration. The lambda returns d[key], which becomes the new accumulated value for the next iteration.

like image 45
Thierry Lathuille Avatar answered Oct 18 '25 07:10

Thierry Lathuille



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!