Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON output sorting in Python

I've a problem with JSON in python.

In fact, if I try to execute this code, python gives me a sorted JSON string!

For example:

values = {
  'profile': 'testprofile',
  'format': 'RSA_RC4_Sealed',
  'enc_key': base64.b64encode(chiave_da_inviare),
  'request': base64.b64encode(data)
}

values_json = json.dumps(values, sort_keys = False, separators = (',', ':'))

And this is the output:

{
  "profile": "testprofile",
  "enc_key": "GBWo[...]NV6w==",
  "request": "TFl[...]uYw==",
  "format": "RSA_RC4_Sealed"
}

As you can see, I tried to use "sort_keys=False" but nothing changed.

How can I stop Python sorting my JSON strings?

like image 722
elledienne Avatar asked May 05 '10 15:05

elledienne


People also ask

How do I sort a JSON key?

Enter your JSON into the first text area, or drag and drop a file, after, select the sort method you're going to use, key value requires the key name (if not specified selects the first key), click the example button to get an idea on how it works. The result will automatically sort and display in the output text area.

Can we sort JSON data?

JSON return type is an array of objects. Hence sort method cannot be used directly to sort the array. However, we can use a comparer function as the argument of the 'sort' method to get the sorting implemented.

What is sort keys parameters in dumps?

Use the sort_keys parameter to specify if the result should be sorted or not: json.dumps(x, indent=4, sort_keys=True) Try it Yourself »


6 Answers

Try OrderedDict from the standard library collections:

>>> import json
>>> from collections import OrderedDict
>>> values = OrderedDict([('profile','testprofile'), 
                          ('format', 'RSA_RC4_Sealed'), 
                          ('enc_key', '...'), 
                          ('request', '...')])
>>> json.dumps(values, sort_keys=False)
'{"profile": "testprofile", "format": "RSA_RC4_Sealed", "enc_key": "...", "request": "..."}'

Unfortunately this feature is New in version 2.7 for collections

like image 73
MrGray Avatar answered Oct 08 '22 07:10

MrGray


You are storing your values into a Python dict which has no inherent notion of ordering at all, it's just a key-to-value map. So your items lose all ordering when you place them into the values variable.

In fact the only way to get a deterministic ordering would be to use sort_keys=True, which I assume places them in alphanumeric ordering. Why is the order so important?

like image 20
Joseph Lisee Avatar answered Oct 08 '22 09:10

Joseph Lisee


An OrderedDict as discussed elsewhere is most of the solution to your problem, and an 'ObjDict' could be even better.

However if you need the order maintained on loading, then you will also need the json.loads() to load the values into an OrderedDict. To do this use

from collections import OrderedDict
values=json.loads(jsontext,object_pairs_hook=OrderedDict)

Otherwise even though the json file will be in order, that order will be lost when loaded.

Perhaps an even better solution is to use 'ObjDict' in place of OrderedDict. This requires a pip install objdict. ObjDict still maintains order, as with OrderedDict, but also brings JSON support and better handling of this example.

from objdict import ObjDict
values = ObjDict("""{"profile" : "testprofile",
      "format": "RSA_RC4_Sealed" }""")
values.enc_key = base64.b64encode(chiave_da_inviare)
values.request = base64.b64encode(data)

values_json = values.dumps(separators=(',', ':'))
like image 20
innov8 Avatar answered Oct 08 '22 08:10

innov8


If you specify sort_keys=False then Python will simply print the items in whatever order they appear in the underlying Python dict object. In some cases this may happen to be the same as the default alphanumeric sort order. In your example, the keys AREN'T even sorted like that, since "format" comes after "request". Regardless, the sort_keys parameter is still valid, as evidenced by this sample code:

>>> import json
>>> json.dumps({"a":5, "b":6, "c":7}, sort_keys=False)
'{"a": 5, "c": 7, "b": 6}'
like image 35
Eli Courtwright Avatar answered Oct 08 '22 07:10

Eli Courtwright


The keys aren't sorted: "profile", "enc_key", "request", "format".

It sounds like you want them to appear in the same order that you created them in the dictionary, but dictionaries are inherently unsorted, they don't remember the order you inserted keys.

There are a number of SortedDict implementations that you can use, but the json encoder won't know to use it to get the keys in the order you want.

like image 34
Ned Batchelder Avatar answered Oct 08 '22 09:10

Ned Batchelder


You can sort json data using simple json.dumps as

sorted_json = json.dumps(values, sort_keys=True)

If you want no need to sort simply provide

unsorted_json = json.dumps(values)  

or:

unsorted_json = json.dumps(values, sort_keys=False)
like image 22
Praveen Avatar answered Oct 08 '22 08:10

Praveen