I am new to Python and I am playing with JSON data. I would like to dynamically build a JSON object by adding some key-value to an existing JSON object.

I tried the following but I get TypeError: 'str' object does not support item assignment:

import json

json_data = json.dumps({})
json_data["key"] = "value"

print 'JSON: ', json_data

You build the object before encoding it to a JSON string:

import json

data = {}
data['key'] = 'value'
json_data = json.dumps(data)

JSON is a serialization format, textual data representing a structure. It is not, itself, that structure.

You can create the Python dictionary and serialize it to JSON in one line and it’s not even ugly.

my_json_string = json.dumps({'key1': val1, 'key2': val2})

There is already a solution provided which allows building a dictionary, (or nested dictionary for more complex data), but if you wish to build an object, then perhaps try ‘ObjDict’. This gives much more control over the json to be created, for example retaining order, and allows building as an object which may be a preferred representation of your concept.

pip install objdict first.

from objdict import ObjDict

data = ObjDict()
data.key = 'value'
json_data = data.dumps()

You can use EasyDict library (doc):

EasyDict allows to access dict values as attributes (works recursively). A Javascript-like properties dot notation for python dicts.

USEAGE

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1

>>> d = edict(foo=3)
>>> d.foo
3

[INSTALLATION]:

  • pip install easydict

All previous answers are correct, here is one more and easy way to do it. For example, create a Dict data structure to serialize and deserialize an object

(Notice None is Null in python and I’m intentionally using this to demonstrate how you can store null and convert it to json null)

import json
print('serialization')
myDictObj = { "name":"John", "age":30, "car":None }
##convert object to json
serialized= json.dumps(myDictObj, sort_keys=True, indent=3)
print(serialized)
## now we are gonna convert json to object
deserialization=json.loads(serialized)
print(deserialization)

enter image description here

  • json.loads take a string as input and returns a dictionary as output.
  • json.dumps take a dictionary as input and returns a string as output.

If you need to convert JSON data into a python object, it can do so with Python3, in one line without additional installations, using SimpleNamespace and object_hook:

from string

import json
from types import SimpleNamespace

string = '{"foo":3, "bar":{"x":1, "y":2}}'

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(string, object_hook=lambda d: SimpleNamespace(**d))

print(x.foo)
print(x.bar.x)
print(x.bar.y)

output:

3
1
2

from file:

JSON object: data.json

{
    "foo": 3,
    "bar": {
        "x": 1,
        "y": 2
    }
}
import json
from types import SimpleNamespace

with open("data.json") as fh:
    string = fh.read()

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(string, object_hook=lambda d: SimpleNamespace(**d))

print(x.foo)
print(x.bar.x)
print(x.bar.y)

output:

3
1
2

from requests

import json
from types import SimpleNamespace
import requests

r = requests.get('https://api.github.com/users/MilovanTomasevic')

# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(r.text, object_hook=lambda d: SimpleNamespace(**d))

print(x.name)
print(x.company)
print(x.blog)

output:

Milovan Tomaševi?
NLB
milovantomasevic.com

For more beautiful and faster access to JSON response from API, take a look at this response.

I create a recursive function to walk a nest dictionary representing the json structure.

  myjson={}
  myjson["Country"]= {"KR": { "id": "220", "name": "South Korea"}}
  myjson["Creative"]= {
                    "1067405": {
                        "id": "1067405",
                        "url": "https://cdn.gowadogo.com/559d1ba1-8d50-4c7f-b3f5-d80f918006e0.jpg"
                    },
                    "1067406": {
                        "id": "1067406",
                        "url": "https://cdn.gowadogo.com/3799a70d-339c-4ecb-bc1f-a959dde675b8.jpg"
                    },
                    "1067407": {
                        "id": "1067407",
                        "url": "https://cdn.gowadogo.com/180af6a5-251d-4aa9-9cd9-51b2fc77d0c6.jpg"
                    }
                }
   myjson["Offer"]= {
                    "advanced_targeting_enabled": "f",
                    "category_name": "E-commerce/ Shopping",
                    "click_lifespan": "168",
                    "conversion_cap": "50",
                    "currency": "USD",
                    "default_payout": "1.5"
                }

   json_data = json.dumps(myjson)

   #reverse back into a json

   paths=[]
   def walk_the_tree(inputDict,suffix=None):
       for key, value in inputDict.items():
            if isinstance(value, dict):
                if suffix==None:
                    suffix=key
                else:
                    suffix+=":"+key

                walk_the_tree(value,suffix)
            else:
                paths.append(suffix+":"+key+":"+value)
 walk_the_tree(myjson)
 print(paths)  

 #split and build your nested dictionary
 json_specs = {}
 for path in paths:
     parts=path.split(':')
     value=(parts[-1])
     d=json_specs
     for p in parts[:-1]:
         if p==parts[-2]:
             d = d.setdefault(p,value)
         else:
             d = d.setdefault(p,{})
    
 print(json_specs)        

 Paths:
 ['Country:KR:id:220', 'Country:KR:name:South Korea', 'Country:Creative:1067405:id:1067405', 'Country:Creative:1067405:url:https://cdn.gowadogo.com/559d1ba1-8d50-4c7f-b3f5-d80f918006e0.jpg', 'Country:Creative:1067405:1067406:id:1067406', 'Country:Creative:1067405:1067406:url:https://cdn.gowadogo.com/3799a70d-339c-4ecb-bc1f-a959dde675b8.jpg', 'Country:Creative:1067405:1067406:1067407:id:1067407', 'Country:Creative:1067405:1067406:1067407:url:https://cdn.gowadogo.com/180af6a5-251d-4aa9-9cd9-51b2fc77d0c6.jpg', 'Country:Creative:Offer:advanced_targeting_enabled:f', 'Country:Creative:Offer:category_name:E-commerce/ Shopping', 'Country:Creative:Offer:click_lifespan:168', 'Country:Creative:Offer:conversion_cap:50', 'Country:Creative:Offer:currency:USD', 'Country:Creative:Offer:default_payout:1.5']