2

Im parsing a complex json string and am working with nested dictionaries and some nested dic.get() functions in my class.

Instead of receiving a None when a higher level key doesn't exist, I would like to find an empty dictionary so that my code (dict.get()) keeps working.

Right now I would like to replace all dictionary values named None with an empty dictionary {}, but I didn't find any good solution how to do it.

So basically I want this:

{'a': {},
 'b': 'Text',
 'c': 5,
 'd': {'d1': {}}

but sadly have that:

{'a': None,
 'b': 'Text',
 'c': 5,
 'd': {'d1': None}
Christian
  • 515
  • 1
  • 6
  • 17

2 Answers2

5

Other solution is to traverse the dictionary recursively and replace the None values:

def replace(d):
    if isinstance(d, dict):
        for k in d:
            if d[k] is None:
                d[k] = {}
            else:
                replace(d[k])
    elif isinstance(d, list):
        for v in d:
            replace(v)


d = {'a': None,
     'b': 'Text',
     'c': 5,
     'd': {'d1': None}}

replace(d)
print(d)

Prints:

{'a': {}, 'b': 'Text', 'c': 5, 'd': {'d1': {}}}
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • That works perfectly! Thank you very much. Tbh I don't understand the elif statement in detail. Didn't know that these kind of circular dependency is possible. The function can take a list of dictionaries, and if it fails its first part and it starts some kind of for loop? – Christian Sep 07 '20 at 13:54
  • 1
    @Christian `elif` just means `else if`. In my code I traverse the dictionary recursively (and handle a case if inside your dictionary is a list - however in your example you don't have any). You can search here on SO for examples/explanation how to search dictionary recursively. For example https://stackoverflow.com/questions/12507206/how-to-completely-traverse-a-complex-dictionary-of-unknown-depth – Andrej Kesely Sep 07 '20 at 16:13
2

You can use the default value for the get method

dict.get("a", {})

Sample:

d = { 'b' : 1,
       'c' : { 'd': 2 } }
print (d.get('a', {}))
print (d.get('c', {}).get('a', {}))
print (d.get('x', {}).get('y', {}).get('z', {}))

output:

{}
{}
{}
mujjiga
  • 16,186
  • 2
  • 33
  • 51
  • Because I have a list of dictionaries in my string and I only want to replace those which are None. Some of them have true values. I also have a lot of keys and I don't want to explictly name them. – Christian Sep 07 '20 at 13:33
  • In your example: You've shown my problem: The c key won't work. If key c has no value, it would be None, and if it's None you can't do [...] .get('a', {})) – Christian Sep 07 '20 at 13:34
  • `d.get('x', {}).get('y', {}).get('z', {})` will work. Its simple then messing up the structure of the json – mujjiga Sep 07 '20 at 13:37
  • No, sadly it doesn't if the value exist as a None. It leads to: AttributeError: 'NoneType' object has no attribute 'get'. It isn't recognized as null so that the condition for {} would be true. – Christian Sep 07 '20 at 13:46