0

Assuming that we have a nested dictionary (or json) and we want to access certain keys/subkeys at various levels, is there a way to send the desired key path to return only the expected data?

If we have a dictionary like the one below:

dct = {'A': {'A1': {'A11': 'something', 'A12': 'something else'}},
       'B': {'B1': 'old thing', 'B2': 'new thing'},
       'C': 'no level'} 

is there an elegant python way of specifying the keys we want to select?

Obviously this works, but is not very elegant...

print(dct['A']['A1']['A12'])
print(dct['B']['B2'])
print(dct['C'])

Ideally, we could have a list of the subset keys we want to return.

pomseb
  • 11
  • 3
  • Another way is to use ```print(dct.get('A', {}).get('A1', {}).get('A12'))``` – abhi May 05 '23 at 20:53
  • Thank you @abhi but I would like to pass the 'key path' as a parameter to a function for instance, instead of having to manually add one .get() for each level... – pomseb May 05 '23 at 21:00
  • ElementTree and XPath have that kind of things for XML reading, maybe someone has made a lib for accessing JSON similarily. "'year' nodes that are children of nodes with name='Singapore':" `root.findall(".//*[@name='Singapore']/year")` https://docs.python.org/3/library/xml.etree.elementtree.html#supported-xpath-syntax . UPDATE, apparently there is JSONPath, https://pypi.org/project/jsonpath-ng/ – antont May 05 '23 at 21:20

1 Answers1

0

Check out glom, it's a quite powerful tool.

Here's a couple of simple examples, but take a look at more complex ones in its tutorial and snippets.

from glom import glom

data = {"name": "John", "age": 30, "address": {"city": "London", "postcode": "SW1A 0AA"}}

postcode = glom(data, "address.postcode")

print(postcode)  # Output: "SW1A 0AA"
data = {"name": "John", "age": 30}

address = glom(data, "address", default="Unknown")

print(address)  # Output: "Unknown"
data = {
    "users": [
        {"name": "John", "age": 30, "city": "London"},
        {"name": "Jane", "age": 25, "city": "Edinburgh"},
        {"name": "Bob", "age": 35, "city": "Manchester"},
    ],
}

# Extracts the names and ages of all the people in the list
users = glom(data, ("users", [{"name": "name", "age": "age"}]))

print(users)  # Output: [{"name": "John", "age": 30}, {"name": "Jane", "age": 25}, {"name": "Bob", "age": 35}]
Anton Petrov
  • 315
  • 1
  • 3
  • 12