[python] JSON 객체의 항목이“json.dumps”를 사용하여 순서가 잘못 되었습니까?

나는 json.dumpsjson으로 변환 하는 데 사용 하고있다.

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, name, timezone 순서대로 키를 원하지만 대신 시간대, id, 이름이 있습니다.

이 문제를 어떻게 해결해야합니까?



답변

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 – 키워드 인수 순서 유지를 참조하십시오 .

귀하의 의견은 JSON으로 지정되고있는 경우, (얻을 수있는 순서를 유지하기 위해 OrderedDict), 당신은 통과 할 수 object_pair_hook, @Fred 얀 코스키에 의해 제안 :

>>> 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)])


답변

다른 사람들이 언급했듯이 기본 dict은 순서가 없습니다. 그러나 파이썬에는 OrderedDict 객체가 있습니다. (최근 Python에 내장되어 있거나 http://code.activestate.com/recipes/576693/에서 사용할 수 있습니다 ).

최신 파이썬 json 구현은 내장 된 OrderedDicts를 올바르게 처리한다고 생각하지만 확실하지 않습니다 (테스트에 쉽게 액세스 할 수 없습니다).

오래된 pythons simplejson 구현은 OrderedDict 객체를 잘 처리하지 못하고 출력하기 전에 일반 dict로 변환합니다.

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가 필요하지 않습니다.


답변

사전의 순서는 정의 된 순서와 아무 관련이 없습니다. 이는 JSON으로 바뀐 사전뿐만 아니라 모든 사전에 해당됩니다.

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

실제로 사전에 도달하기 전에 사전이 “거꾸로”바뀌 었습니다 json.dumps.

>>> {"id":1,"name":"David","timezone":3}
{'timezone': 3, 'id': 1, 'name': 'David'}


답변

이 답변에 너무 늦다는 것을 알고 있지만 sort_keys를 추가하고 다음과 같이 false를 할당하십시오.

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

이것은 나를 위해 일했다


답변

json.dump ()는 사전의 순서를 유지합니다. 텍스트 편집기에서 파일을 열면 볼 수 있습니다. OrderedDict 전송 여부에 관계없이 주문을 보존합니다.

그러나 json.load ()는 JFSebastian이 위에서 지시 한 것처럼 object_pairs_hook 매개 변수를 사용하여 OrderedDict ()로로드하도록 지시하지 않으면 저장된 객체의 순서를 잃습니다.

일반적인 조작에서는 저장된 사전 오브젝트를 일반 dict에로드하고 일반 dict는 제공된 항목의 순서를 유지하지 않으므로 순서를 잃게됩니다.


답변

Javascript에서와 같이 JSON에서 객체 키의 순서는 의미가 없으므로 어떤 순서로 표시되는지는 중요하지 않으며 동일한 객체입니다.


답변