Editing Existing JSON in Python

Jesse Jashinsky picture Jesse Jashinsky · Feb 1, 2011 · Viewed 11.2k times · Source

I'm pulling in some JSON from a server in the given format:

{"images": [{"rating": 5.0, "thumburl": "http://something.jpg", "description": "dfgd", "submitdate": "2011-01-29T07:54:02", "submituser": "J", "imagekey": "a"}, ...]}

I have to add a new element "viewurl" to each element using the "imagekey." For example, the result would be

{"images": [{"rating": 5.0, "thumburl": "http://something.jpg", "description": "dfgd", "submitdate": "2011-01-29T07:54:02", "submituser": "J", "imagekey": "a", "viewurl": "/view?imagekey=a"}, ...]}

There's probably an easy way to do this, but I'm having trouble finding much on simplejson other than dumps and load.

Answer

sberry picture sberry · Feb 1, 2011

Is this what you are trying to do?

data = simplejson.loads(yourString)
for image in data['images']:
    image['viewurl'] = '/view?imagekey=%s' %(image['imagekey'])

You could also use an object_hook. This works for your example, but you may want to tweak it a bit depending on your actual data:

>>> def addImageKey(dataPart):
...     if dataPart.has_key('imagekey'):
...         dataPart['viewurl'] = '/view?imagekey=%s' %dataPart['imagekey']
...     return dataPart
... 
>>> decoded_with_viewurl = json.loads(myString, object_hook = addImageKey)

The reason I mention the possibility of a need to tweak it is because in it's current form, the addImageKey object_hook will add the viewurl key/value to any object within your JSON structure that contains an imagekey key already. So, you may have to use something more specific to the items in images if need be.

Oh, and if you want to encode it back to a JSON string, you could just change the last line to

>>> reencoded_with_viewurl = json.dumps(json.loads(myString, object_hook = addImageKey))

Depending on the amount of data you are decoding/encoding, I would suggest the possibility of using cjson to re-encode the data. It is lightning fast in comparison to simplejson/json. Unfortunately it does not have support for things like object_hook.