374

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

8 Answers 8

747

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Your solution worked like a charm for me. I couldn't understand the meaning of your last line though, could you please elaborate that a bit. Thanks.
@akki: the OP tried to treat the JSON string (a series of characters that encode an object) as the object itself. They tried to use json_data['key'] = 'value', which won't work because json_data is not a Python dictionary.
given an object can one transform the object into JSON or a dictionary somehow automatically?
@CharlieParker: that's way too broad. Python objects are not that simply reflected into JSON, as JSON is quite a limited format with only a few data types. There are a lot of questions here on SO already that cover specific object types and JSON, such as Django or SQLAlchemy models, etc.
@AlexJohnson: pip list gives you the same information and can output JSON: pip list --format=json
|
46

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

Comments

25

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

2 Comments

this is exactly what I was looking for! Given that dicts are unordered, though you could sort by alphabetical order when calling json.dumps i.e. json.dumps(response, sort_keys=True, indent=4), but then you're stuck with alphabetical order and not your preferred ordering, grouping and representation
The JSON specification does not allow for ordered properties on JSON objects and any endpoint expecting specific ordering of properties on an object will be disappointed. If specific ordering is required, you will need to place your values in an array within the object.
25
  • 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.

Comments

15

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

Comments

14

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

1 Comment

Benyamin, could you please edit your example to show usage with JSON dumps and loads?
2

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

1 Comment

see for reversing paths to nested dictionaries (stackoverflow.com/questions/2738141/…)
0

You can create a JSON file by using the jsonCreator module

jsonCreator.createJson(dict, "fileName", ["path"])

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.