2010-05-05 49 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=(',', ':'))