Могу ли я получить JSON для загрузки в OrderedDict?


хорошо, поэтому я могу использовать OrderedDict в json.dump. То есть, OrderedDict может использоваться в качестве входных данных для JSON.

но можно ли его использовать в качестве вывода? Если да, то как? В моем случае я бы хотел load в OrderedDict, чтобы я мог сохранить порядок ключей в файле.

Если нет, есть ли какой-нибудь обходной путь?

6 351

6 ответов:

Да, вы можете. При указании до JSONDecoder. Фактически, это точный пример, приведенный в документации.

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

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

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

или для Python 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 теперь сохраняет порядок по умолчанию. Обратите внимание на разницу в поведении между python 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
}

в реализации cPython python 3.6:

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

действительно отличная новость заключается в том, что это стало спецификацией языка с python 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 не имеют порядка).

Это действительно приятно воспользоваться тем, что json сбрасывает OrderedDict в правильном порядке. Однако, это вообще излишне тяжело и не обязательно имеет смысл читать все JSON словари как OrderedDict (через

обычно используемая команда load будет работать, если вы укажете object_pairs_hook