178

私はjson.dumpsのようなjsonに変換するために使用しています

countries.append({"id":row.id,"name":row.name,"timezone":row.timezone})
print json.dumps(countries)

私が持っている結果は次のとおりです。

[
   {"timezone": 4, "id": 1, "name": "Mauritius"}, 
   {"timezone": 2, "id": 2, "name": "France"}, 
   {"timezone": 1, "id": 3, "name": "England"}, 
   {"timezone": -4, "id": 4, "name": "USA"}
]

ID、名前、タイムゾーンの順序でキーを配置したいのですが、代わりにタイムゾーン、ID、名前があります。

これを修正するにはどうすればよいですか?

4

8 に答える 8

281

Python dict(Python 3.7 より前) と JSON オブジェクトはどちらも順序付けられていないコレクションです。sort_keysパラメータを渡して、キーを並べ替えることができます。

>>> import json
>>> json.dumps({'a': 1, 'b': 2})
'{"b": 2, "a": 1}'
>>> json.dumps({'a': 1, 'b': 2}, sort_keys=True)
'{"a": 1, "b": 2}'

特定の注文が必要な場合; あなたが使用することができますcollections.OrderedDict

>>> from collections import OrderedDict
>>> json.dumps(OrderedDict([("a", 1), ("b", 2)]))
'{"a": 1, "b": 2}'
>>> json.dumps(OrderedDict([("b", 2), ("a", 1)]))
'{"b": 2, "a": 1}'

Python 3.6 以降、キーワード引数の順序は保持され、上記はより適切な構文を使用して書き直すことができます。

>>> json.dumps(OrderedDict(a=1, b=2))
'{"a": 1, "b": 2}'
>>> json.dumps(OrderedDict(b=2, a=1))
'{"b": 2, "a": 1}'

PEP 468 – Preserving Keyword Argument Orderを参照してください。

入力が JSON として与えられた場合、@Fred Yankowski で提案されているように 、順序を保持するために ( get を取得するためにOrderedDict) を渡すことができます。object_pair_hook

>>> json.loads('{"a": 1, "b": 2}', object_pairs_hook=OrderedDict)
OrderedDict([('a', 1), ('b', 2)])
>>> json.loads('{"b": 2, "a": 1}', object_pairs_hook=OrderedDict)
OrderedDict([('b', 2), ('a', 1)])
于 2014-05-23T03:14:57.673 に答える
23

他の人が言及したように、基になる辞書は順不同です。ただし、Python には OrderedDict オブジェクトがあります。(これらは最近の python に組み込まれています。または、これを使用できます: http://code.activestate.com/recipes/576693/ )。

新しいpythons json実装は組み込みのOrderedDictsを正しく処理すると思いますが、よくわかりません(そしてテストに簡単にアクセスできません)。

古い pythons simplejson 実装は OrderedDict オブジェクトを適切に処理しません..出力する前にそれらを通常の辞書に変換します..しかし、次のことを行うことでこれを克服できます:

class OrderedJsonEncoder( simplejson.JSONEncoder ):
   def encode(self,o):
      if isinstance(o,OrderedDict.OrderedDict):
         return "{" + ",".join( [ self.encode(k)+":"+self.encode(v) for (k,v) in o.iteritems() ] ) + "}"
      else:
         return simplejson.JSONEncoder.encode(self, o)

これを使用すると、次のようになります。

>>> import OrderedDict
>>> unordered={"id":123,"name":"a_name","timezone":"tz"}
>>> ordered = OrderedDict.OrderedDict( [("id",123), ("name","a_name"), ("timezone","tz")] )
>>> e = OrderedJsonEncoder()
>>> print e.encode( unordered )
{"timezone": "tz", "id": 123, "name": "a_name"}
>>> print e.encode( ordered )
{"id":123,"name":"a_name","timezone":"tz"}

これはほとんど希望どおりです。

別の代替手段は、行クラスを直接使用するようにエンコーダーを特殊化することです。そうすれば、中間の dict または UnorderedDict は必要ありません。

于 2012-06-01T04:55:41.543 に答える
11

ちょっと私はそれがこの答えにとても遅れていることを知っていますが、次のように sort_keys を追加してそれに false を割り当てます:

json.dumps({'****': ***},sort_keys=False)

これは私のために働いた

于 2019-07-19T18:20:52.497 に答える
8

ディクショナリの順序は、それが定義された順序とは関係ありません。これは、JSON に変換されたものだけでなく、すべてのディクショナリに当てはまります。

>>> {"b": 1, "a": 2}
{'a': 2, 'b': 1}

実際、辞書は、到達する前に「逆さま」になりましたjson.dumps

>>> {"id":1,"name":"David","timezone":3}
{'timezone': 3, 'id': 1, 'name': 'David'}
于 2012-06-01T03:37:30.540 に答える
6

json.dump() は、辞書の順序を保持します。ファイルをテキスト エディタで開くと表示されます。OrderedDict を送信するかどうかに関係なく、順序が保持されます。

しかし、json.load() は、JFSebastian が上記で指示したように、object_pairs_hook パラメーターで行われる OrderedDict() にロードするように指示しない限り、保存されたオブジェクトの順序を失います。

通常の操作では、保存された辞書オブジェクトを通常の dict にロードし、通常の dict は指定された項目の順序を保持しないため、順序が失われます。

于 2016-10-20T19:46:30.450 に答える
1

Michael Anderson の回答に基づいていますが、配列を渡すときにも機能します

class OrderedJsonEncoder(simplejson.JSONEncoder):
    def encode(self, o, first=True):
        if type(o) == list and first:
            return '[' + ",".join([self.encode(val, first=False) for val in o]) + ']'
        if type(o) == OrderedDict:
            return "{" + ",".join(
                [self.encode(k, first=False) + ":" + self.encode(v) for (k, v) in o.iteritems()]
            ) + "}"
        else:
            return simplejson.JSONEncoder.encode(self, o)
于 2021-11-13T02:12:06.960 に答える
-1

Python 3.7+ を使用している場合、順序は保持されます。

Python 3.7 より前では、dict は順序付けが保証されていなかったため、collections.OrderedDict が特に要求されない限り、入力と出力は通常スクランブルされていました。Python 3.7 から、通常の dict は順序を保持するようになったため、JSON の生成と解析のために collections.OrderedDict を指定する必要がなくなりました。

https://docs.python.org/3/library/json.html#json.dump

于 2021-05-05T08:28:51.963 に答える