I have a large dictionary (originally a json), something like this:
dictionary = {
"Thing1": {
"Thing1.1": {
"Thing1.1.1": "Text",
"Thing1.1.2": "Text",
"Thing1.1.3": "Text"},
"Thing1.2": [{
"Thing1.2.1.1": "Text",
"Thing1.2.1.2": "Text",
"Thing1.2.1.3": "Text"},
{
"Thing1.2.2.1": "Text",
"Thing1.2.2.2": "Text",
"Thing1.2.2.3": "Text we're interested in"}
],
"Thing1.3": {
"Thing1.3.1": "Text",
"Thing1.3.2": "Text",
"Thing1.3.3": "Text"}
},
"Thing2": {
"Thing2.1": {
"Thing2.1.1": "Text",
"Thing2.1.2": "Text",
"Thing2.1.3": "Text"},
"Thing2.2": {
"Thing2.2.1": "Text",
"Thing2.2.2": "Text",
"Thing2.2.3": "Text"},
"Thing2.3": {
"Thing2.3.1": "Text",
"Thing2.3.2": "Text",
"Thing2.3.3": "Text"}
},
"Thing3": {
"Thing3.1": {
"Thing3.1.1": "Text",
"Thing3.1.2": "Text",
"Thing3.1.3": "Text"},
"Thing3.2": {
"Thing3.2.1": "Text",
"Thing3.2.2": "Text",
"Thing3.2.3": "Text"},
"Thing3.3": {
"Thing3.3.1": "Text",
"Thing3.3.2": "Text",
"Thing3.3.3": "Text"}
}
}
And, having automated some things, I have some keys the values of which I'm interested in, in a string as such:
key = '["Thing1"]["Thing1.2"][1]["Thing1.2.2.3"]''
and I'd like to be able to call the value for which I have the key as if it was the following:
value = dictionary["Thing1"]["Thing1.2"][1]["Thing1.2.2.3"]
I have tried using exec, and formatting everything neatly using f-strings, however that's horrible and it does give me some trouble of its own, especially if I use it in functions due to the way it handles global and local variables.
Edit: I've changed the dictionary and key to represent what it looks more like in the real case: This is a dictionary of arbitrary depth that may contain lists embedded within it e.g. 'Thing1.2'.
Let's assume that the depth of the nested dictionaries is unknown. In that case we need a loop to navigate it. You can use a regular expression to isolate the embedded keys. Something like this:
import re
dictionary = {
"Thing1": {
"Thing1.1": {
"Thing1.1.1": "Text",
"Thing1.1.2": "Text",
"Thing1.1.3": "Text"},
"Thing1.2": [{
"Thing1.2.1.1": "Text",
"Thing1.2.1.2": "Text",
"Thing1.2.1.3": "Text"},
{
"Thing1.2.2.1": "Text",
"Thing1.2.2.2": "Text",
"Thing1.2.2.3": "Text we're interested in"}
],
"Thing1.3": {
"Thing1.3.1": "Text",
"Thing1.3.2": "Text",
"Thing1.3.3": "Text"}
},
"Thing2": {
"Thing2.1": {
"Thing2.1.1": "Text",
"Thing2.1.2": "Text",
"Thing2.1.3": "Text"},
"Thing2.2": {
"Thing2.2.1": "Text",
"Thing2.2.2": "Text",
"Thing2.2.3": "Text"},
"Thing2.3": {
"Thing2.3.1": "Text",
"Thing2.3.2": "Text",
"Thing2.3.3": "Text"}
},
"Thing3": {
"Thing3.1": {
"Thing3.1.1": "Text",
"Thing3.1.2": "Text",
"Thing3.1.3": "Text"},
"Thing3.2": {
"Thing3.2.1": "Text",
"Thing3.2.2": "Text",
"Thing3.2.3": "Text"},
"Thing3.3": {
"Thing3.3.1": "Text",
"Thing3.3.2": "Text",
"Thing3.3.3": "Text"}
}
}
key = '["Thing1"]["Thing1.2"][1]["Thing1.2.2.3"]'
list_ = re.findall(r'\["*(.*?)"*\]', key)
d = dictionary
for k in list_:
if k.isdigit() and isinstance(d, list):
d = d[int(k)]
else:
d = d.get(k)
if d is None:
break
print(d)
Output:
Text we're interested in