1

I need to show an output like below as a result of a webservice call

{
  "predictions": [
    {
      "id": 18009,
      "cuisine": "italian",
      "probability": 0.17846838753494407
    },
    {
      "id": 28583,
      "cuisine": "italian",
      "probability": 0.1918703125538735
    }
  ]
}

I have the below code to create the object:

    json_data = []
    for i in range (0, len(predicted_labels)):
        data = {}
        data['id'] = int(test['id'][i])
        data['cuisine'] = categoricalTransformer[predicted_labels[i]]
        item = predicted_probability[i]
        data['probability'] = item[predicted_labels[i]]
        json_data.append(data)
    json_return = {"predictions":json_data}
    return jsonify(json_return)

which reorders the key alphabetically as shown below.

{
  "predictions": [
    {
      "cuisine": "italian",
      "id": 18009,
      "probability": 0.17846838753494407
    },
    {
      "cuisine": "italian",
      "id": 28583,
      "probability": 0.1918703125538735
    }
  ]
}

What should I do?

2
  • 6
    There is no key order in a Json object. Commented Jan 7, 2019 at 2:22
  • 5
    Why is the key order relevant? Commented Jan 7, 2019 at 2:23

2 Answers 2

4

Rebuild your new dictionary with a collections.defaultdict(), and append ordered dictionaries with a collections.OrderedDict():

from collections import OrderedDict
from collections import defaultdict
from json import dumps

data = {
    "predictions": [
        {"id": 18009, "cuisine": "italian", "probability": 0.17846838753494407},
        {"id": 28583, "cuisine": "italian", "probability": 0.1918703125538735},
    ]
}

key_order = ["id", "cuisine", "probability"]

result = defaultdict(list)
for dic in data["predictions"]:
    ordered = OrderedDict((key, dic.get(key)) for key in key_order)
    result["predictions"].append(ordered)

print(dumps(result))
# {"predictions": [{"id": 18009, "cuisine": "italian", "probability": 0.17846838753494407}, {"id": 28583, "cuisine": "italian", "probability": 0.1918703125538735}]}

json.dumps() here serializes the dictionary into a JSON formatted string.

Note: If you are using Python3.6+, you can use normal dictionaries instead of OrderedDict(), since insertion order of keys is remembered. However, in 3.6 it is an implementation feature, whereas in 3.7 it is a language feature. You read more about this at Are dictionaries ordered in Python 3.6+?.

You can probably rely on this feature for applications that have a minimum requirement of Python3.6. Furthermore, its probably safer to user OrderedDict() anyways, so your code can be backwards compatible for all python versions.

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

3 Comments

Although you are correct that Python 3.6+ remembers insertion order, this behaviour is a side-effect of an implementation change and should not be relied on. For more future-proof code and greater reusability, OrderedDict should be used.
@Grismar Yes thats a very good point, cheers.
@Grismar This is correct for 3.6 only. Since Python 3.7 it is a documented feature. Still backward compatibility should be considered.
0

You can look into Ordered Dictionary. It remembers the insertion order, and you would be able to organise your json via this collection this way.

Example:

datadict = {'a':'a', 'c':'c', 'b':'b'}
import collections

print (collections.OrderedDict(datadict))
#OrderedDict([('a':'a'), ('c':'c'), ('b':'b')])

x = collections.OrderedDict(datadict)
print (dict(x))
#{'a':'a', 'c':'c', 'b':'b'}

print (x == datadict)
#True


print (collections.OrderedDict(sorted(datadict.items(), key=lambda t:t[0])))
#OrderedDict([('a':'a'), ('b':'b'), ('c':'c')])

z = collections.OrderedDict(sorted(datadict.items(), key=lambda t:t[0]))
print (dict(z))
#{'a':'a', 'b':'b', 'c':'c'}

print (z == datadict)
#True

Using this, you can convert your json_return dict object into an OrderedDict with your desired insertion order and then return that OrderedDict object or convert it back into a dict and return that dict

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.