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
сохранить данный порядок?
Ответы
Ответ 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"}}