Manthan Jamdagni
Manthan Jamdagni

Reputation: 1031

Elegant way to set values in a nested json in python

I am setting up some values in a nested JSON. In the JSON, it is not necessary that the keys would always be present.
My sample code looks like below.

if 'key' not in data:
    data['key'] = {}
if 'nested_key' not in data['key']:
    data['key']['nested_key'] = some_value

Is there any other elegant way to achieve this? Simply assigning the value without if's like - data['key']['nested_key'] = some_value can sometimes throw KeyError.

I referred multiple similar questions about "getting nested JSON" on StackOverflow but none fulfilled my requirement. So I have added a new question. In case, this is a duplicate question then I'll remove this one once guided towards the right question.

Thanks

Upvotes: 0

Views: 3739

Answers (2)

Jay
Jay

Reputation: 24915

Please note that, for the insertion you need not check for the key and you can directly add it. But, defaultdict can be used. It is particularly helpful incase of values like lists.

from collections import defaultdict

data = defaultdict(dict)
data['key']['nested_key'] = some_value

defaultdict will ensure that you will never get a key error. If the key doesn't exist, it returns an empty object of the type with which you have initialized it.

List based example:

from collections import defaultdict

data = defaultdict(list)
data['key'].append(1)

which otherwise will have to be done like below:

data = {}
if 'key' not in data:
    data['key'] = ['1']
else:
    data['key'].append('2')

Example based on existing dict:

from collections import defaultdict

data = {'key1': 'sample'}    
data_new = defaultdict(dict,data)    
data_new['key']['something'] = 'nothing'

print data_new

Output:

defaultdict(<type 'dict'>, {'key1': 'sample', 'key': {'something': 'nothing'}})

Upvotes: 3

rene-d
rene-d

Reputation: 343

You can write in one statement:

data.setdefault('key', {})['nested_value'] = some_value

but I am not sure it looks more elegant.

PS: if you prefer to use defaultdict as proposed by Jay, you can initialize the new dict with the original one returned by json.loads(), then passes it to json.dumps():

data2 = defaultdict(dict, data)
data2['key'] = value
json.dumps(data2)    # print the expected dict

Upvotes: 2

Related Questions