Сортировка вывода JSON в Python


у меня проблема с JSON в python.

на самом деле, если я попытаюсь выполнить этот код, python дает мне отсортированную строку JSON!

например:

values = {'profile' : 'testprofile', 
          'format': 'RSA_RC4_Sealed', 
          'enc_key' : base64.b64encode(chiave_da_inviare), 
          'request' : base64.b64encode(data)
      }


values_json = json.dumps(values, sort_keys=False, separators=(',', ':'))

и это выход:

{"profile":"testprofile","enc_key":"GBWo[...]NV6w==","request":"TFl[...]uYw==","format":"RSA_RC4_Sealed"}

Как вы можете видеть, я пытался использовать "sort_keys=False", но ничего не изменилось.

Как я могу остановить Python сортировку моих строк JSON?

6 51

6 ответов:

вы храните свои значения в python дикт который не имеет никакого врожденного понятия упорядочения вообще, это просто ключ => карта значений. Таким образом, ваши товары теряют весь порядок, когда вы помещаете их в переменную "values".

на самом деле единственным способом получить детерминированный порядок было бы использовать "sort_keys=True", который, как я предполагаю, помещает их в алфавитно-цифровой порядок. Почему этот приказ так важен?

попробовать OrderedDict из стандартной библиотеки collections:

>>> import json
>>> from collections import OrderedDict
>>> values = OrderedDict([('profile','testprofile'), 
                          ('format', 'RSA_RC4_Sealed'), 
                          ('enc_key', '...'), 
                          ('request', '...')])
>>> json.dumps(values, sort_keys=False)
'{"profile": "testprofile", "format": "RSA_RC4_Sealed", "enc_key": "...", "request": "..."}'

к сожалению, эта функция New in version 2.7 на collections

OrderedDict, как обсуждалось в другом месте, является большей частью решения вашей проблемы, и "ObjDict" может быть еще лучше.

однако если вам нужен заказ, поддерживаемый при загрузке, то вам также понадобится json.loads () для загрузки значений в OrderedDict. Для этого используйте

from collections import OrderedDict
values=json.loads(jsontext,object_pairs_hook=OrderedDict)

в противном случае, даже если файл json будет в порядке, этот порядок будет потерян при загрузке.

возможно, еще лучшим решением является использование 'ObjDict' вместо OrderedDict. Для этого требуется pip install objdict. ObjDict по-прежнему поддерживает порядок, как и в OrderedDict, но также обеспечивает поддержку JSON и лучшую обработку этого примера.

from objdict import ObjDict
values = ObjDict("""{"profile" : "testprofile",
      "format": "RSA_RC4_Sealed" }""")
values.enc_key = base64.b64encode(chiave_da_inviare)
values.request = base64.b64encode(data)

values_json = values.dumps(separators=(',', ':'))

если указать sort_keys=False тогда Python просто напечатает элементы в любом порядке, в котором они появляются в базовом объекте Python dict. В некоторых случаях это может оказаться таким же, как алфавитно-цифровой порядок сортировки по умолчанию. В вашем примере ключи даже не сортируются так, поскольку " формат "приходит после"запроса". Несмотря на это,sort_keys параметр все еще действителен, о чем свидетельствует этот пример кода:

>>> import json
>>> json.dumps({"a":5, "b":6, "c":7}, sort_keys=False)
'{"a": 5, "c": 7, "b": 6}'

ключи не сортируются: "профиль", "enc_key", "запрос", "формат".

похоже, что вы хотите, чтобы они отображались в том же порядке, в котором вы их создали в словаре, но словари по своей сути несортированы, они не помнят порядок, в котором вы вставили ключи.

Существует ряд реализаций SortedDict, которые вы можете использовать, но кодировщик json не будет знать, чтобы использовать его для получения ключей в нужном порядке.

вы можете сортировать данные json с помощью простого json.свалки как

sotred_json = json.dumps(values, sort_keys=True)

Если вы не хотите, чтобы сортировать просто предоставить

unsotred_json = json.dumps(values)  or unsotred_json = json.dumps(values, sort_keys=False)