#python #json #sorting
#python #json #сортировка
Вопрос:
Мне нужно выполнить полный рекурсивный алфавитный порядок для объекта JSON в python.
Причина в том, чтобы иметь возможность различать два файла json.
Учитывая этот ввод:
{
"request-id": "12345",
"version": "1.1.4",
"multi": {
"one": 1,
"two": 2.0,
"Abc": [3,2,4,1, null],
"three": null,
"list": [
{"lb1": 2.1},
{"lb": 2.2},
{"la": 3},
{"mix_list": [1, {"bb":1}, 2, {"aa":1}]}]
}
}
это ожидаемый результат:
{
"multi": {
"Abc": [1,2,3,4,null],
"list": [
{"la": 3},
{"lb": 2.2},
{"lb1": 2.1},
{ "mix_list": [1, 2, {"aa": 1}, {"bb": 1}] }
],
"one": 1,
"three": null,
"two": 2.0
},
"request-id": "12345",
"version": "1.1.4"
}
РЕДАКТИРОВАТЬ: чтобы иметь возможность выполнять различие, он также должен упорядочивать элементы массива.
Ответ №1:
Для этого вы можете использовать json.dump/s
собственный kwarg sort_keys
.
a_json = json.dumps(json_object, sort_keys=True)
print(a_json)
Комментарии:
1.
sort_keys
сортирует ключи, но не значения массива, поэтому недостаточно различать два файла json. Я уточнил свой вопрос.
Ответ №2:
Объект JSON — это простой объект dict. До версии 3.7 у dicts не было порядка, поэтому сначала вам нужно преобразовать его в OrderedDict, а затем добавить каждый элемент json в правильном порядке. порядок. С 3.7 вы можете полагаться на стандартный порядок dict .
Объекты с ключами сортируются в соответствии с их ключами, объекты внутри списка сортируются по их «отсортированному рекурсивному строковому представлению», в то время как примитивные значения сортируются в соответствии с их естественным порядком.
import json
from operator import itemgetter
# replace all three {} with OrderedDict() for python <= 3.6
def sorted_json(js, result):
def norm_str(s):
# because of str special handling of single quotes
return str(s).replace("'", '"')
if type(js) in [int, str, bool, float] or js is None:
return js
if type(js) == list:
res = [sorted_json(i, {}) for i in js]
return sorted(res, key=norm_str)
items = sorted(js.items(), key=itemgetter(0))
for k, v in items:
result[k] = sorted_json(v, {})
return result
Сортировка чувствительна к регистру.
Вы можете использовать его таким образом:
json_data = json.loads(json_text)
res = sorted_json(json_data, {})
print(json.dumps(res, indent=4))
Комментарии:
1. Формально порядок @superbrain гарантируется только с версии 3.7 (в 3.6 на него «не следует полагаться»). Я исправлю свой ответ, чтобы было понятно.
2. @superbrain разумно иметь это в виду, если вы хотите изменить код python старше двух с половиной лет. Возможно, это все еще большая часть кода python.