yohhoyの日記

技術的メモをしていきたい日記

順序維持してJSONデータを読み込む

Python標準モジュール json ではJSONデコード結果を辞書型(dict)にて表現するため、入力JSON文字列中でのオブジェクトname/value出現順序が維持されない。

2018-04-16追記:Python 3.7以降ではdict型の順序維持が仕様上保証されるようになる。Python 3.7 – Dictionaries now ordered参照。

json.loadメソッドまたはJSONDecoderクラスの名前付き引数object_pairs_hookcollections.OrderedDictを指定すると、デコード結果がOrderedDict型にて表現されることで出現順序が維持される。

import collections
import json

json_data = '{"C": 1, "B": 2, "A": 3}'

decoder = json.JSONDecoder()
print(decoder.decode(json_data))
# {'B': 2, 'C': 1, 'A': 3} など

decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
print(decoder.decode(json_data))
# OrderedDict([('C', 1), ('B', 2), ('A', 3)])

Python言語のdict型は順序性について強い保証を持たないため、どのような順序となるかは各処理系に依存する。CPython 3.6ではdict型の順序が維持されるよう実装変更が行われたが、言語仕様上は依然としてdict型に対する順序規定は存在しない。*1

関連URL

*1:4.10.1. Dictionary view objects: "Keys and values are iterated over in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary's history of insertions and deletions."