【问题标题】:JSON output sorting in PythonPython中的JSON输出排序
【发布时间】:2011-02-15 23:47:29
【问题描述】:

我在 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 = (',', ':'))

这是输出:

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

如您所见,我尝试使用“sort_keys=False”但没有任何改变。

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

【问题讨论】:

标签: python json sorting


【解决方案1】:

试试标准库collections中的OrderedDict

>>> 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 for collections

【讨论】:

  • +1 为所提问题提供简单而直接的答案
  • 该功能适用​​于旧版本的 Python,使用 pip install ordereddict 然后将导入行更改为 from ordereddict import OrderedDict,如 this answer 所述(在 Python 2.6.6 上测试)。
  • 很好......但请注意,令人惊讶的是,虽然这适用于 json 2.0.9,但它不适用于 simplejson 2.0.9(即序列化中不保留顺序)(据说只是外部安装的 json 版本?!)。 Python 版本为 2.7.3。
【解决方案2】:

您将值存储到 Python dict 中,它根本没有固有的排序概念,它只是一个键值映射。因此,当您将物品放入 values 变量时,它们会丢失所有排序。

事实上,获得确定性排序的唯一方法是使用sort_keys=True,我假设它们以字母数字顺序排列。为什么顺序如此重要?

【讨论】:

  • 因为我认为我的代码不起作用,因为顺序不正确。有可能吗?
  • 您的代码工作正常,只是订单未定义。如果您想始终保持一致,请使用“sort_keys=True”。
  • 如果我想按值而不是键排序怎么办?
  • 至少有一个非常正当的理由要对这些进行排序:如果您想对字典进行哈希处理以便稍后快速确定字典是否相同但不能存储原始字典,您需要字典的确定性表示。
【解决方案3】:

在其他地方讨论的 OrderedDict 是解决问题的大部分方法,而“ObjDict”可能会更好。

但是,如果您需要在加载时保持顺序,那么您还需要 json.loads() 将值加载到 OrderedDict 中。为此,请使用

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

否则即使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=(',', ':'))

【讨论】:

    【解决方案4】:

    如果您指定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}'
    

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

        【解决方案6】:

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

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

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

        unsorted_json = json.dumps(values)  
        

        或:

        unsorted_json = json.dumps(values, sort_keys=False)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-04
          • 2020-08-27
          • 1970-01-01
          • 1970-01-01
          • 2020-03-16
          • 2020-03-23
          • 2010-10-27
          • 1970-01-01
          相关资源
          最近更新 更多