Подтвердить что ты не робот

Json.dumps отменяет порядок

Я работаю с json module, создавая файл json, содержащий записи подобного

json.dumps({"fields": { "name": "%s", "city": "%s", "status": "%s", "country": "%s" }})

Однако в созданном файле json поля находятся в неправильном порядке

{"fields": {"status": "%s", "city": "%s", "name": "%s", "country": "%s"}}

что является проблемой, поскольку подстановки для %s -строг теперь неверны.

Как я могу заставить функцию dumps сохранить данный порядок?

4b9b3361

Ответ 1

Как и другие ответы правильно, до Python 3.6 словари не упорядочены.

Тем не менее, JSON также должен иметь неупорядоченные отображения, поэтому в принципе нет смысла хранить упорядоченные словари в JSON. Конкретно это означает, что при чтении объекта JSON порядок возвращаемых ключей может быть произвольным.

Поэтому хорошим способом сохранения порядка отображения (например, Python OrderedDict) в JSON является вывод массива пар (ключ, значение), которые вы преобразуете обратно в упорядоченное отображение при чтении:

>>> from collections import OrderedDict
>>> import json
>>> d = OrderedDict([(1, 10), (2, 20)])                                         
>>> print d[2]
20
>>> json_format = json.dumps(d.items())                   
>>> print json_format  # Order maintained
[[1, 10], [2, 20]]
>>> OrderedDict(json.loads(json_format))  # Reading from JSON: works!
OrderedDict([(1, 10), (2, 20)])
>>> _[2]  # This works!
20

(Обратите внимание, как упорядоченный словарь составлен из списка пар (ключ, значение): OrderedDict({1:10, 2: 20}) не будет работать: его ключи не обязательно упорядочены, как в OrderedDict({1:10, 2: 20}) словаря, так как литерал создает словарь Python, ключи которого неупорядочены.)

PS: Начиная с Python 3.1, модули json предлагают ловушку для автоматического преобразования списка пар (как выше) в что-то еще, например, OrderedDict.

Ответ 2

Вы можете выбрать OrderedDict вместо обычного dict при создании объекта json для запоминания порядка вставки:

>>> from collections import OrderedDict
>>> a = '{"fields": { "name": "%s", "city": "%s", "status": "%s", "country": "%s" }}'
>>> b = json.loads(a, object_pairs_hook=OrderedDict)
>>> json.dumps(b)
'{"fields": {"name": "%s", "city": "%s", "status": "%s", "country": "%s"}}'

Ответ 3

Это словарь, а словари не сохраняют порядок. Вместо этого вы можете использовать OrderedDict.

Вы также можете добавить параметр sort_keys = False:

json.dumps(values, sort_keys=False)

Ответ 4

Вы не можете создать OrderedDict из dict, потому что заказ уже изменился с момента создания словаря. Лучше всего использовать кортежи для создания OrderedDict

from collections import OrderedDict
import json

a = (("name","foo"),("city","bar"),("status","baz"),("country","my"))

b = OrderedDict(a)

c = {"fileds": b}

print json.dumps(c)
Output:
{"fileds": {"name": "foo", "city": "bar", "status": "baz", "country": "my"}}