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')