0

Lets say I have some json like so store in a variable called data

{
  "print": {
    "ams": { "exists": 1},
    "fan_speed": 29,
    "reports": [
      {"name": "foo"},
      {"name": "bar"}
    ]
  }
}

Now I've got a variable which is the key i want to return stored in a variable called key for example print.fan_speed, print.ams.exists, print.reports[0].name

What I want to is something like data.get(key). What is the best way to approach this?

K20GH
  • 6,032
  • 20
  • 78
  • 118
  • 1
    The best way is to write a function that navigates the dictionary looking for the key you're interested in – DarkKnight Jan 11 '23 at 16:39
  • The key variable doesnt have to be in dot notation, i just need a way to programmatically structure this – K20GH Jan 11 '23 at 16:48

1 Answers1

0

The following should work its way into your data, including indexing into lists:

import re

data = {
  "print": {
    "ams": { "exists": 1},
    "fan_speed": 29,
    "reports": [
      {"name": "foo"},
      {"name": "bar"}
    ]
  }
}

def value_of(data, location):
    for part in location.split("."):
        match = re.match(r"(.*)\[(\d+)\]$", part)
        if match:
            name, index = match.groups()
            data = data.get(name)[int(index)]
        else:
            data = data.get(part)
        if not data:
            return None
    return data

print(value_of(data, "print.ams.exists"))
print(value_of(data, "print.reports[1].name"))

Result:

1
bar

It could do with a little rationalisation as it will return None for a non-existent key, but will error on a bad index - it should do one or the other depending on your requirements but the concept is there.

The concept is to take each '.' separated element of the string in turn, using it to dig further into the data structure. If the element matches the syntax of 'name[index]' using the regex, the component is treated as a list and the indexth element is extracted.

Thickycat
  • 894
  • 6
  • 12
  • This is what I was thinking of yes, thanks! However what would happen here if I wanted to get say `print.reports[0].name` – K20GH Jan 11 '23 at 22:50
  • Then you need to check for your subscript syntax and extract the name and index as in the modified answer. – Thickycat Jan 12 '23 at 14:56