Home > Software engineering >  Check if a JSON attribute exists
Check if a JSON attribute exists

Time:09-30

I'm trying to check if certain attributes exist in JSON data, which is stored as a dictionary:

import json

testJsonString = """
{
    "a": {
        "b": {
            "c": {
                "x": "Value One",
                "y": "Value Two"
            }
        }
    }
}
"""

testDict = json.loads(testJsonString)

if 'a' in testDict:
    if 'b' in testDict['a']:
        if 'c' in testDict['a']['b']:
            if 'x' in testDict['a']['b']['c']:
                print(testDict['a']['b']['c']['x'])
            if 'y' in testDict['a']['b']['c']:
                print(testDict['a']['b']['c']['y'])

This prints, as desired:

Value One
Value Two

However, if one of the top level nested attributes is null (converted to None by json.loads()):


testJsonString = """
{
    "a": {
        "b": null
    }
}
"""

I get the following error:

if 'c' in testDict['a']['b']:
TypeError: argument of type 'NoneType' is not iterable

Is there a way to handle this? I'm stumped.

CodePudding user response:

Working with nested dicts in Python is a pain, I recommend using: https://github.com/cdgriffith/Box

from box import Box

def unwrap(b: Box) -> Optional[Box]:
    return None if b == Box() else b

box = Box(testDict)
value = unwrap(box.a.b.c.x)
if value is not None:
    print(value)

CodePudding user response:

I fixed it by adding a None check for every if level. Not sure if this is the best way to go about it, but it works:

testJsonString = """
{
    "a": {
        "b": {
            "c": {
                "x": "Value One",
                "y": "Value Two"
            }
        }
    }
}
"""

testDict = json.loads(testJsonString)

if testDict and 'a' in testDict:
    if testDict['a'] and 'b' in testDict['a']:
        if testDict['a']['b'] and 'c' in testDict['a']['b']:
            if testDict['a']['b']['c'] and 'x' in testDict['a']['b']['c']:
                print(testDict['a']['b']['c']['x'])
            if testDict['a']['b']['c'] and 'y' in testDict['a']['b']['c']:
                print(testDict['a']['b']['c']['y'])

CodePudding user response:

You can use a user defined function to check with null safety

import json

def Check(key, col):
    return key in col if col is not None else False

testJsonString = """
{
    "a": {
        "b": null
    }
}
"""

testDict = json.loads(testJsonString)

if Check('a', testDict):
    if Check('b', testDict['a']):
        if Check('c', testDict['a']['b']):
            if Check('x', testDict['a']['b']['c']):
                print(testDict['a']['b']['c']['x'])
            if Check('y', testDict['a']['b']['c']):
                print(testDict['a']['b']['c']['y'])

Another option a quick one but a dirty approach to handle errors is by using try/except

import json

testJsonString = """
{
    "a": {
        "b": {
            "c": {
                "x": "Value One",
                "y": "Value Two"
            }
        }
    }
}
"""

testDict = json.loads(testJsonString)

try:
    if 'a' in testDict:
        if 'b' in testDict['a']:
            if 'c' in testDict['a']['b']:
                if 'x' in testDict['a']['b']['c']:
                    print(testDict['a']['b']['c']['x'])
                if 'y' in testDict['a']['b']['c']:
                    print(testDict['a']['b']['c']['y'])
except:
    print('Something went wrong in the dictionary')
  • Related