8

I am trying ot sort a JSON Object using Python.

I have the following object :

{ 
  "text": "hello world",
  "predictions": 
   [
     {"class": "Class 1", "percentage": 4.63},
     {"class": "Class 2", "percentage": 74.68},
     {"class": "Class 3", "percentage": 9.38},
     {"class": "Class 4", "percentage": 5.78},
     {"class": "Class 5", "percentage": 5.53}
   ]
}

And I want to have this object instead :

{ 
  "text": "hello world",
  "predictions": 
   [
     {"class": "Class 2", "percentage": 74.68},
     {"class": "Class 3", "percentage": 9.38},
     {"class": "Class 4", "percentage": 5.78},
     {"class": "Class 5", "percentage": 5.53},
     {"class": "Class 1", "percentage": 4.63}
   ]
}

In fact, I want to order my array of objects by percentage.

I have tried this command :

sorted_obj = sorted(json_obj['predictions'], key=lambda k: k['percentage'], reverse=True)

And I had this error :

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string indices must be integers

Any help is needed,

Thanks

7
  • 1
    JSON arrays are parsed to Python lists and JSON objects to Python dicts. dicts are unordered in Python. You would need some ordered container. Try to store the data in an OrderedDict: from collections import OrderedDict Commented Apr 6, 2017 at 13:00
  • I trust you realise "nothing worked" is an unhelpful description of your problem. It implies it's the reader's duty to determine the exact nature of the problem. Most people will walk away, others like me will add a comment intended to be helpful, but very few will attempt to answer such an ill-defined question. Give yourself a chance to get help, tell us what's wrong! Commented Apr 6, 2017 at 13:01
  • 2
    @Adirio - he isn't trying to order a dict, he's trying to order a list of dicts based on one of the values in the dicts. Commented Apr 6, 2017 at 13:02
  • 1
    I edited the post :) Commented Apr 6, 2017 at 13:07
  • 1
    @Adirio yeah, made similar mistakes myself a million times, no sweat. Commented Apr 6, 2017 at 16:26

2 Answers 2

16

You can use sorted to sort the values, something like this :

json_obj = { 
  "text": "hello world",
  "predictions": 
   [
     {"class": "Class 1", "percentage": 4.63},
     {"class": "Class 2", "percentage": 74.68},
     {"class": "Class 3", "percentage": 9.38},
     {"class": "Class 4", "percentage": 5.78},
     {"class": "Class 5", "percentage": 5.53}
   ]
}

sorted_obj = dict(json_obj) 
sorted_obj['predictions'] = sorted(json_obj['predictions'], key=lambda x : x['percentage'], reverse=True)

print(sorted_obj)
print(json_obj)

This will result in :

# The sorted values based on 'predictions' -> 'percentage'
{'predictions': [{'percentage': 74.68, 'class': 'Class 2'}, {'percentage': 9.38, 'class': 'Class 3'}, {'percentage': 5.78, 'class': 'Class 4'}, {'percentage': 5.53, 'class': 'Class 5'}, {'percentage': 4.63, 'class': 'Class 1'}], 'text': 'hello world'}

# The original json_obj will remain unchanged as we have created a new object sorted_obj from values of json_obj using dict()
{'text': 'hello world', 'predictions': [{'class': 'Class 1', 'percentage': 4.63}, {'class': 'Class 2', 'percentage': 74.68}, {'class': 'Class 3', 'percentage': 9.38}, {'class': 'Class 4', 'percentage': 5.78}, {'class': 'Class 5', 'percentage': 5.53}]}
Sign up to request clarification or add additional context in comments.

4 Comments

Note that this is an in-place edit of the original json. It will overwrite it.
@AshishNitinPatil No, it wont. I am creating new object using the old values and not creating a direct reference.
My bad, I thought replacing list in a key should change the original as well.
Why have you done this? sorted_obj = dict(json_obj) , whats its significance?
2

You are almost right, you probably want to create a copy of the dictionary and then replace predictions's value to the sorted object. I'm assuming that you want to leave the original json_obj unchanged, hence the deepcopy (although it is unnecessary if we are simply doing a reassignment instead of in-place .sort).

>>> json_obj = { 
...   "text": "hello world",
...   "predictions": 
...    [
...      {"class": "Class 1", "percentage": 4.63},
...      {"class": "Class 2", "percentage": 74.68},
...      {"class": "Class 3", "percentage": 9.38},
...      {"class": "Class 4", "percentage": 5.78},
...      {"class": "Class 5", "percentage": 5.53}
...    ]
... }
>>> from copy import deepcopy
>>> sorted_json_obj = deepcopy(json_obj)
>>> sorted_json_obj['predictions'] = sorted(json_obj['predictions'], key=lambda k: k['percentage'], reverse=True)
>>> sorted_json_obj
{'predictions': [{'class': 'Class 2', 'percentage': 74.68},
                 {'class': 'Class 3', 'percentage': 9.38},
                 {'class': 'Class 4', 'percentage': 5.78},
                 {'class': 'Class 5', 'percentage': 5.53},
                 {'class': 'Class 1', 'percentage': 4.63}],
 'text': 'hello world'}

3 Comments

My bad, my object wasn't well parsed. Thanks for your time :)
@ben @Ashish Note : For simple data structures, using deepcopy can be an overkill, since it does so much accounting, reference tracking, and the like. Look at this : writeonly.wordpress.com/2009/05/07/…
Yep, reassignment would be okay here, but in-place sorting won't be. Had a great discussion in chat about it. Thanks @SatishGarg!

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.