1

Due to a very helpful person on this site, I have been able to put together a script which takes user names (inputted by user) and then use a loop to append each of those user names to a specific JSON structure. However, I have noticed that the order within my JSON dump is not maintained. For example, here is what my loop and JSON dump looks like:

list_users = []
for user in users:
    list_users.append({"name": user,
                       "member": 123,
                       "comment": "this is a comment"})

json_user_list_encoding = json.dumps(list_users, indent=2)

My print looks like this:

({"member": 123,
  "comment": "this is a comment"
  "name": user
  })

I was wondering if it was possible to maintain the same order in "list_users" when I use the JSON dump. I have looked at this site a bit and from what I have read, I will have to assign keys in order to maintain a specific order. However, I am not sure how to do this being that I only have one JSON object. I hope this make sense. Thanks for the help.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
user7681184
  • 893
  • 2
  • 12
  • 24
  • 2
    Dictionary elements are inherently an unordered data structure. `{"a": 1, "b": 2}` is exactly the same as `{"b": 2, "a": 1}` -- they'll pass an equality check, &c. – Charles Duffy Mar 10 '17 at 17:05
  • why do you need ordering? – acushner Mar 10 '17 at 17:05
  • ...which is to say, even if you **did** assign the keys yourself (`d={}; d["a"]=1; d["b"]=2`), you'd **still** have no ordering guarantees, because the assignment order and the storage/output order have no relationship between them guaranteed by documented semantics (whether there's a relationship *in practice* depends on hashing algorithm details that are implementation-defined). – Charles Duffy Mar 10 '17 at 17:06
  • As of Python 3.6, `dict` *does* maintain the order that the keys are inserted. For portability, you can use `collections.OrderedDict`. However I agree with the above commenters, if a `dict` is the correct structure, there's probably no need for ordered entries. – BallpointBen Mar 10 '17 at 17:11
  • Json is not ordered, python dictionaries are not ordered. If your purpose is to make the order predictable, so that (for example) the Json file can be usefully put into source control, then any order will do. – Ben Mar 10 '17 at 17:27
  • @BallpointBen Python 3.6 dict doesn't maintain the order that keys are inserted. **CPython** 3.6 dict does. Python 3.6 only says that keyword arguments will arrive in order in the `kwargs` mapping. – wim Mar 10 '17 at 17:29
  • Thanks for the clarification – BallpointBen Mar 10 '17 at 17:30

1 Answers1

8

If you just want them ordered reliably/repeatably, but don't care about the order itself, then json dumps accepts a sort_keys kwarg that can help:

>>> json.dumps({'z': 3, 'b': 2, 'a': 1})
'{"a": 1, "z": 3, "b": 2}'
>>> json.dumps({'z': 3, 'b': 2, 'a': 1}, sort_keys=True)
'{"a": 1, "b": 2, "z": 3}'

Otherwise, put the users in an OrderedDict instead of a plain dict.

from collections import OrderedDict

list_users.append(OrderedDict([
    ("name", user),
    ("member", 123),
    ("comment", "this is a comment"),
]))

If you need them to deserialize to the same order too, use the object_pairs_hook when loading.

wim
  • 338,267
  • 99
  • 616
  • 750