web-dev-qa-db-ja.com

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 = False」を使用しようとしましたが、何も変わりませんでした。

Python JSON文字列のソートを停止するにはどうすればよいですか?

57
elledienne

値をpython dict に格納しています。これは、順序付けの固有の概念をまったく持たず、単なるキー=>値マップです。したがって、アイテムはすべての順序付けを失います。それらを「値」変数に配置するとき。

実際、決定論的な順序を取得する唯一の方法は、「sort_keys = True」を使用することです。なぜ順序がそれほど重要なのですか?

53
Joseph Lisee

標準ライブラリの 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 for collections

93
MrGray

他の場所で説明されているOrderedDictは、ほとんどの問題の解決策であり、「ObjDict」の方がさらに優れている可能性があります。

ただし、読み込み時に順序を維持する必要がある場合は、json.loads()を使用して値をOrderedDictに読み込む必要もあります。これを行うには

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

そうしないと、jsonファイルが正常に配置されていても、ロード時にその順序が失われます。

おそらく、より優れたソリューションは、OrderedDictの代わりに「ObjDict」を使用することです。これには、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=(',', ':'))
15
innov8

sort_keys=Falseを指定すると、Pythonは単純に、基礎となるPython dictオブジェクトに表示される順序でアイテムを印刷します。あなたの例では、キーは「format」が「request」の後に来るため、キーはそのようにソートされていません。それにもかかわらず、sort_keysパラメータはまだ有効です。このサンプルコードから明らかです。

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

キーはソートされていません:「profile」、「enc_key」、「request」、「format」。

辞書で作成したのと同じ順序で表示したいようですが、辞書は本質的にソートされておらず、キーを挿入した順序を覚えていません。

使用できるSortedDictの実装は多数ありますが、jsonエンコーダーはそれを使用してキーを希望の順序で取得することを知りません。

4
Ned Batchelder

単純なjson.dumpsを使用してjsonデータをソートできます。

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

ソートする必要がない場合は、単に提供します

unsotred_json = json.dumps(values)  

または:

unsotred_json = json.dumps(values, sort_keys=False)
2
Praveen