Reputation: 5766
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 :)
Upvotes: 3
Views: 1753
Reputation: 14236
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
Upvotes: 10
Reputation: 23825
Traverse the data structure like this:
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))
Output:
[12, 67, 45]
Upvotes: 1
Reputation: 17322
you can use a recursive approach
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
Upvotes: 1
Reputation: 24288
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.
Upvotes: 2