Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON keys are shuffled in Python

I'm parsing the JSON from the web api, and Python seems to shuffle the keys when I iterate over them.

Original JSON on screenshot (it's right original ordering. No, it's not just alphabetically sorted): Original JSON

My code:

data = requests.get('http://www.dota2.com/jsfeed/heropediadata?feeds=abilitydata&l=english').json()

for key in data['abilitydata']:
    print key

And output:

tiny_avalanche
rubick_fade_bolt
doom_bringer_devour
undying_flesh_golem
...

I've also tried to do this via urllib & json.loads() — it gives the same result.

How can I can achieve the original ordering?

like image 769
artem Avatar asked Aug 20 '15 19:08

artem


People also ask

Does JSON preserve key order?

Yes, the order of elements in JSON arrays is preserved.

How do you arrange JSON in Python?

Using json. dumps() function is one way to sort the JSON object. It is used to convert the array of JSON objects into a sorted JSON object. The value of the sort_keys argument of the dumps() function will require to set True to generate the sorted JSON objects from the array of JSON objects.

Can JSON have same key?

There is no "error" if you use more than one key with the same name, but in JSON, the last key with the same name is the one that is going to be used. In your case, the key "name" would be better to contain an array as it's value, instead of having a number of keys "name".

Does Python use JSON formatting?

Javascript Object Notation abbreviated as JSON is a light-weight data interchange format. It Encode Python objects as JSON strings, and decode JSON strings into Python objects .

How to get the keys and values of a JSON file?

data = json.load(jsonFile) Then you have a Python object. Now you can get the keys and values. The code below depends on what your json file looks like.

How to iterate through JSON with keys in Python?

To iterate through JSON with keys, we have to first import the JSON module and parse the JSON file using the ‘load’ method as shown below. It will parse the ‘json_multidimensional.json’ file as the dictionary ‘my_dict’. Now to iterate with keys, see the below code.

What is the use of shuffle in Python?

Definition and Usage. The shuffle () method takes a sequence, like a list, and reorganize the order of the items. Note: This method changes the original list, it does not return a new list.

How to handle JSON data using Python?

In this article, we will discuss how to handle JSON data using Python. Python provides a module called json which comes with Python’s standard built-in utility. Note: In Python, JSON data is usually represented as a string. To use any module in Python it is always needed to import that module.


2 Answers

You can use an ordered dictionary and the object_pairs_hook argument of the loads method in the json package. Here is a working code example:

import json
import requests
from collections import OrderedDict

result = requests.get('http://www.dota2.com/jsfeed/heropediadata?feeds=abilitydata&l=english')
data = json.loads(result.text, object_pairs_hook = OrderedDict)

data will contain your dictionary keys in order

like image 112
Jopela Avatar answered Sep 22 '22 23:09

Jopela


As the others have said, dict is unordered. collections.OrderedDict is a dict subclass whose keys are ordered. The problem is that json.load returns a dict directly, and we can't just throw the result in an OrderedDict, as the order of the keys is already lost information by this point.

We need a way of telling json.load to return an OrderedDict instead of a dict.This can be done by implementing a custom json.JSONDecoder which supplies an object_pairs_hook. The object_pairs_hook is given a JSON object as a list of (key, value) tuples in the order that they appear in the JSON document. It should return the translation of this object to a Python object. We'll hand this list of tuples to the initializer for collections.OrderedDict, and that should do the trick.

Here's some code:

data = """
{
    "foo": "bar",
    "a_list": [1, 2, 3],
    "another_object": {
        "c": 3,
        "a": 1,
        "b": 2
        },
    "last_key": 42
}
"""

decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
result = decoder.decode(data)
print(result)

which gives:

OrderedDict([('foo', 'bar'),
             ('a_list', [1, 2, 3]),
             ('another_object', OrderedDict([('c', 3), ('a', 1), ('b', 2)])),
             ('last_key', 42)])

Lastly, you might be wondering: "why is this so much extra work?". Well, JSON isn't meant to be treated as a data structure with any fixed order. You're going against the grain by doing this.

like image 43
jme Avatar answered Sep 19 '22 23:09

jme