8

I have problem when I want to convert json string to Python dictionary. I have string like

 s={"name":{"Saban:Saulic"},"price":{"koncert:1000"} ....}

when I write something like

tags=json.loads(s)

I gtet dictionary but order of keys is not the same like in string ( it is not name, price ...). How to convert json string to dictionary and save order in keys ?

Damir
  • 54,277
  • 94
  • 246
  • 365
  • 2
    Python dictionaries are unordered, which is fine because normally you access the entries *by key* and if you have to iterate over the elements, the order does usually not matter. Btw, `s` is neither a string nor a dictionary not valid JSON if it was a string. It looks like you are after a different structure, such as an array of objects: `[{"name": "...", "price": "..."}, ...]`. If you provide some explanation for *why* you need the keys in order and provide a correct example, then we can help you better. – Felix Kling Apr 18 '12 at 09:51
  • There is not really such a thing as "order of keys" in a `dict`. You can iterate over them one at a time, but there is no control over what order you get them in. – Karl Knechtel Apr 18 '12 at 10:05
  • 3
    I think [this previous](http://stackoverflow.com/questions/6921699/can-i-get-json-to-load-into-an-ordereddict-in-python) question here on Stackoverflow provides an answer. – Alvin Apr 18 '12 at 10:06

1 Answers1

22

Since Python 2.7 you have OrderedDict module from collections

This kind of dictionary preserves the insertion order of elements.

From Python docs:

json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Deserialize fp (a .read()-supporting file-like object containing a JSON document) to a Python object.

If the contents of fp are encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate encoding name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and should be wrapped with codecs.getreader(encoding)(fp), or simply decoded to a unicode object and passed to loads().

object_hook is an optional function that will be called with the result of any object literal decoded (a dict). The return value of object_hook will be used instead of the dict. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting).

object_pairs_hook is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of object_pairs_hook will be used instead of the dict. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict() will remember the order of insertion). If object_hook is also defined, the object_pairs_hook takes priority.

I think you could use object_pairs_hook parameter with collections.OrderedDict()

tags=json.loads(s, object_pairs_hook=collections.OrderedDict)
jesterjunk
  • 2,342
  • 22
  • 18
Diego Navarro
  • 9,316
  • 3
  • 26
  • 33