2015-05-15 3 views
0

Я пытаюсь получить ответ от http://steamcommunity.com/profiles/76561198081591043/inventory/json/730/2 в python с использованием запросов.Преобразование в json переупорядочивает объекты в python

import requests  
url = "http://steamcommunity.com/profiles/76561198081591043/inventory/json/730/2" 
r = requests.get(url) 
print r.text 
print r.json() 

r.text и r.json() возвращают объекты упорядоченные по-другому. В «rgInventory», например, первые 3 "ids": в .text конец в 925, 658, 891, но в .json() конец в 891, 619, 741 (просто совпадение, что они спускаются).

json.loads(r.text) дает тот же результат

Как я получить json объекты в том же порядке, как .text показывает их?

+2

Вы не делаете , JSON Objects отображает словари Python, которые по своей сути неупорядочены. –

+0

не столько «неупорядоченный», сколько «произвольно заказанный»: порядок элементов определяется на основе хеширующей функции, которая зависит от вашего конкретного вкуса Python и на нее нельзя положиться. есть ли причина, почему его нужно заказывать точно так же, как в тексте? – oxymor0n

+0

Я не понимаю неупорядоченную часть, если я использую iteritems() для циклического прохождения объекта (r ['rgInventory'] [i] ['id'] и печатаю это, я всегда получаю их обратно в том же порядок, как показано печатью –

ответ

2

Это, вероятно, не нужно, и если необходимо, либо ваш код, либо API Steam нарушен. Судя по вашим комментариям, это, вероятно, не нужно. Тем не менее, это выполнимо.

json.loads принимает необязательный аргумент object_pairs_hook. Это указывает функцию, которая будет вызываться с помощью списка пар ключ-значение для декодирования литералов объекта. Значение по умолчанию эквивалентно заданию object_pairs_hook=dict; чтобы сохранить порядок ключи появились в сыром тексте, вы можете использовать object_pairs_hook=collections.OrderedDict:

import collections, json 
data = json.loads(response_string, object_pairs_hook=collections.OrderedDict) 

r.json() проходит именованные аргументы вместе с json.loads, поэтому она должна поддерживать один и тот же аргумент:

data = r.json(object_pairs_hook=collections.OrderedDict) 
+0

Это необходимо только потому, что у пара нет надлежащего API для инвентарей, и возвращаемые текстовые значения в порядке последнего времени, поэтому для проверки обновлений инвентаря это проще всего, спасибо за ответ, я попробую его в ругающий –

0

Порядок полей в объекте JSON явно бессмыслен и не нуждается в сохранении. Многие реализации являются хэш-таблицами, для эффективности.

Если вопрос JSON имеет значение, вы должны использовать массив - в этом случае простейшей моделью может быть массив, содержащий двухэлементные массивы, каждый из которых, в свою очередь, содержит имя строки и значение.

Другим решением будет использование кода обработки строки, отличного от JSON, для обработки полей объектов JSON обратно в ваш предпочтительный порядок. Не рекомендуется!

Извините, но разница, которую спецификация не распознает, просто не является отличием.

Смежные вопросы