Python中的JSON输出排序

ell*_*nne 57 python sorting json

我在python中遇到了JSON的问题.

事实上,如果我尝试执行此代码,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=(',', ':'))
Run Code Online (Sandbox Code Playgroud)

这是输出:

{"profile":"testprofile","enc_key":"GBWo[...]NV6w==","request":"TFl[...]uYw==","format":"RSA_RC4_Sealed"}
Run Code Online (Sandbox Code Playgroud)

如你所见,我试图使用"sort_keys = False",但没有任何改变.

如何阻止Python对JSON字符串进行排序?

小智 94

试试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": "..."}'
Run Code Online (Sandbox Code Playgroud)

不幸的是,此功能适用New in version 2.7collections

  • +1为所提问题提供简单但直接的答案 (6认同)

Jos*_*see 53

您将值存储到python dict中,它根本没有排序的概念,它只是一个key => value map.因此,当您将它们放入"值"变量时,您的项目将失去所有排序.

事实上,获得确定性排序的唯一方法是使用"sort_keys = True",我假设将它们放在字母数字排序中.为什么订单如此重要?

  • 您的代码工作正常,只是订单未定义.如果要始终保持一致,请使用"sort_keys = True". (9认同)
  • 请注意,[自 Python 3.7 起,`dict` 默认记住它们的插入顺序](https://docs.python.org/3/library/collections.html#ordereddict-objects)。 (5认同)
  • 如果我想按值而不是按键排序怎么办? (3认同)
  • 想要对这些进行排序至少有一个非常充分的理由:如果您想对字典进行哈希处理以便稍后快速确定字典是否相同但无法存储原始字典,则需要字典的确定性表示。 (3认同)

inn*_*ov8 15

如其他地方所讨论的OrderedDict是您问题的大多数解决方案,而'ObjDict'可能会更好.

但是,如果您需要在加载时维护订单,那么您还需要json.loads()将值加载到OrderedDict中.要做到这一点

from collections import OrderedDict
values=json.loads(jsontext,object_pairs_hook=OrderedDict)
Run Code Online (Sandbox Code Playgroud)

否则,即使json文件按顺序排列,加载时该命令也会丢失.

或许更好的解决方案是使用'ObjDict'代替OrderedDict.这需要一个pip install objdict.与OrderedDict一样,ObjDict仍然保持顺序,但也带来了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=(',', ':'))
Run Code Online (Sandbox Code Playgroud)


Eli*_*ght 6

如果你指定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}'
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用简单的 json.dumps 对 json 数据进行排序

sorted_json = json.dumps(values, sort_keys=True)
Run Code Online (Sandbox Code Playgroud)

如果您不想排序,只需提供

unsorted_json = json.dumps(values)  
Run Code Online (Sandbox Code Playgroud)

或者:

unsorted_json = json.dumps(values, sort_keys=False)
Run Code Online (Sandbox Code Playgroud)


Ned*_*der 5

键没有排序:“profile”、“enc_key”、“request”、“format”。

听起来您希望它们以您在字典中创建它们的相同顺序出现,但字典本质上是未排序的,它们不记得您插入键的顺序。

您可以使用许多 SortedDict 实现,但 json 编码器不知道使用它来按您想要的顺序获取键。