[python] JSON을 OrderedDict에로드 할 수 있습니까?

Ok에서 OrderedDict를 사용할 수 있습니다 json.dump. 즉, OrderedDict를 JSON에 대한 입력으로 사용할 수 있습니다.

그러나 출력으로 사용할 수 있습니까? 그렇다면 어떻게? 제 경우 load에는 OrderedDict 에 들어가서 파일의 키 순서를 유지할 수 있습니다.

그렇지 않은 경우 해결 방법이 있습니까?



답변

그래 넌 할수있어. JSONDecoder에object_pairs_hook 인수를 지정합니다 . 실제로 이것은 설명서에 제공된 정확한 예입니다.

>>> json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')
OrderedDict([('foo', 1), ('bar', 2)])
>>> 

다음과 같이이 매개 변수를 전달할 수 있습니다 json.loads(다른 목적으로 Decoder 인스턴스가 필요하지 않은 경우).

>>> import json
>>> from collections import OrderedDict
>>> data = json.loads('{"foo":1, "bar": 2}', object_pairs_hook=OrderedDict)
>>> print json.dumps(data, indent=4)
{
    "foo": 1,
    "bar": 2
}
>>> 

사용은 json.load같은 방식으로 이루어집니다 :

>>> data = json.load(open('config.json'), object_pairs_hook=OrderedDict)


답변

Python 2.7+ 용 단순 버전

my_ordered_dict = json.loads(json_str, object_pairs_hook=collections.OrderedDict)

또는 파이썬 2.4에서 2.6까지

import simplejson as json
import ordereddict

my_ordered_dict = json.loads(json_str, object_pairs_hook=ordereddict.OrderedDict)


답변

좋은 소식이 있습니다! 버전 3.6부터 cPython 구현은 사전의 삽입 순서 ( https://mail.python.org/pipermail/python-dev/2016-September/146327.html )를 유지했습니다. 이것은 json 라이브러리가 기본적으로 순서 보존을 의미합니다. 파이썬 3.5와 3.6의 동작 차이를 관찰하십시오. 코드:

import json
data = json.loads('{"foo":1, "bar":2, "fiddle":{"bar":2, "foo":1}}')
print(json.dumps(data, indent=4))

py3.5에서는 결과 순서가 정의되지 않았습니다.

{
    "fiddle": {
        "bar": 2,
        "foo": 1
    },
    "bar": 2,
    "foo": 1
}

파이썬 3.6의 cPython 구현에서 :

{
    "foo": 1,
    "bar": 2,
    "fiddle": {
        "bar": 2,
        "foo": 1
    }
}

정말 좋은 소식은 이것이 파이썬 3.7 (cPython 3.6 이상의 구현 세부 사항과 반대) 인 언어 사양이되었다는 것입니다 : https://mail.python.org/pipermail/python-dev/2017-December/151283 .html

따라서 귀하의 질문에 대한 답변은 이제 python 3.6으로 업그레이드하십시오! 🙂


답변

dict를 덤프하는 것 외에도 항상 키 목록을 작성한 다음 목록을 OrderedDict반복하여 키 목록 을 재구성 할 수 있습니까?


답변

사전과 함께 순서가 지정된 키 목록을 덤프하는 것 외에도 명시 적이라는 이점이있는 또 다른 최첨단 솔루션은 키-값 쌍의 (순서가 지정된) 목록을 덤프하는 것입니다. ordered_dict.items() . 로딩은 간단하다 OrderedDict(<list of key-value pairs>). JSON에는이 개념이 없다는 사실에도 불구하고 정렬 된 사전을 처리합니다 (JSON 사전에는 순서가 없습니다).

jsonOrderedDict를 올바른 순서로 덤프 한다는 사실을 활용하는 것이 좋습니다 . 그러나 일반적으로 모든 JSON 사전을 object_pairs_hook인수를 통해 OrderedDict로 읽어야하는 것은 불필요하게 무겁고 의미가 없으므로 주문해야하는 사전 명시 적으로 변환 하는 것도 의미가 있습니다.


답변

object_pairs_hook 매개 변수 를 지정하면 일반적으로 사용되는로드 명령이 작동합니다 .

import json
from  collections import OrderedDict
with open('foo.json', 'r') as fp:
    metrics_types = json.load(fp, object_pairs_hook=OrderedDict)


답변