2010-05-05 33 views
46

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

,这是输出:

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

正如你所看到的,我试图用 “sort_keys =假”,但什么都没有改变。

如何停止Python排序我的JSON字符串?

回答

43

您正在将您的值存储到python dict中,它根本没有固有的排序概念,它只是一个key => value映射。所以当你把它们放到“values”变量中时,你的物品就会失去所有的顺序。

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

+0

因为我认为我的代码不工作,因为顺序是不正确的。可能吗? – elledienne 2010-05-05 15:53:23

+7

您的代码工作正常,只是订单未定义。如果你想始终使用“sort_keys = True”。 – 2010-05-05 15:56:44

+0

谢谢!我解决了!你摇滚;) – elledienne 2010-05-05 16:47:01

4

这些密钥没有排序:“profile”,“enc_key”,“request”,“format”。

听起来好像你希望它们按照你在字典中创建它们的顺序出现,但是字典本质上是未排序的,它们不记得你插入的键的顺序。

你可以使用一些SortedDict实现,但是json编码器不知道用它来按你想要的顺序得到键。

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}' 
82

从标准库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.7collections

+4

+1,用于提供简单而直接的回答问题 – mloskot 2013-01-15 12:53:41

+0

此功能可用于使用'pip install ordereddict'的较旧版本的Python,然后将导入行更改为'from ordereddict import OrderedDict',如[本答案]中所述( http://stackoverflow.com/a/6852800/892951)(在Python 2.6.6上测试)。 – chirale 2013-12-16 09:46:11

+0

不错...但注意,令人惊讶的是,虽然这适用于json 2.0.9,但它不起作用(即顺序不会保留在序列化中)与simplejson 2.0.9(这应该只是json的外部安装版本?!) 。 Python版本是2.7.3。 – 2014-10-08 05:07:30

9

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

但是,如果您需要加载时保留的顺序,那么您还需要使用json.loads()将值加载到OrderedDict中。要做到这一点使用

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

否则,即使json文件将按顺序,该订单将被加载时丢失。

也许更好的解决方案是使用'ObjDict'来代替OrderedDict。 这需要一个pip安装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=(',', ':'))