#python #python-3.x
#python #python-3.x
Вопрос:
Я всегда думал, что словари неупорядочены, это означает, что мы должны были использовать что-то вроде OrderedDict, чтобы заставить его запоминать порядок вставки.
Когда я увидел документы python, было упомянуто, что из python 3.7 dict упорядочен.
У меня мало сомнений в этом,
- Если dict сохраняет порядок вставки, означает ли это, что даже коллекции
defaultdict
in также будут делать то же самое? - Как насчет функций json.dumps и json.loads с данными defaultdict, если у меня есть данные, подобные приведенным ниже,
РЕДАКТИРОВАТЬ: https://docs.python.org/3/library/json.html (документация json)
До Python 3.7 порядок dict не гарантировался, поэтому входные и выходные данные обычно скремблировались, если не было коллекций.Специально был запрошен OrderedDict . Начиная с Python 3.7, обычный dict стал сохранять порядок, поэтому больше нет необходимости указывать коллекции.OrderedDict для генерации и синтаксического анализа JSON.
Что касается второго сомнения, я нашел приведенное выше утверждение в документах python json, но я хотел знать, будет ли это применимо для вложенных данных defaultdict.
# example defaultdict data for 2 doubt.
from collections import defaultdict
data = defaultdict(dict)
data["0"]["a"] = "Google"
data["0"]["b"] = "Google"
data["0"]["c"] = "Google"
data["1"]["a"] = "Google"
data["1"]["b"] = "Google"
data["1"]["c"] = "Google"
data["2"]["a"] = "Google"
data["2"]["b"] = "Google"
data["2"]["c"] = "Google"
data["3"]["c"] = "Google"
data["3"]["b"] = "Google"
data["3"]["a"] = "Google"
json.dumps(data) # will these operations preserve the order
json.loads(data)
Я пробовал это, и это сохраняло порядок, но я хотел быть уверенным, что это всегда сохранит порядок независимо.
Комментарии:
1. Разве не было бы проще просто попробовать это?
2. Что произошло, когда вы попробовали это?
3. В документации говорится: » defaultdict является подклассом встроенного класса dict . Он переопределяет один метод и добавляет одну переменную экземпляра, доступную для записи. Остальные функциональные возможности такие же, как и для класса dict, и здесь не документированы. »
4. defaultdict и JSON — это совершенно разные проблемы — они относятся к двум вопросам.
5. Формат JSON не поддерживает порядок в объектах json.org/json-en.html
Ответ №1:
Python диктует
Начиная с python 3.7, реализация dict упорядочивается как часть спецификации, а не как побочный эффект реализации, поэтому ее можно использовать надежно. OrderedDict по-прежнему полезен по нескольким причинам:
- обратная совместимость (если вам нужно поддерживать более старые версии python)
- измените порядок ключей с помощью move_to_end и pop_item
- более четкое намерение: если вы полагаетесь на то, что ключи dict упорядочены, OrderedDict делает это очевидным, но вы теряете некоторую производительность
- порядок ключей учитывается при сравнении OrderedDicts и игнорируется для dicts (спасибо @ShadowRanger за уведомление):
Например:
from collections import OrderedDict
one_dict = {"a": 1, "b": 2}
another_dict = {"b": 2, "a": 1}
one_ordered_dict = OrderedDict(a=1, b=2)
another_ordered_dict = OrderedDict(b=2, a=1)
print(one_dict == another_dict)
# True
print(one_ordered_dict == another_ordered_dict)
# False
Если требуется какое-либо из этих требований, вам может помочь OrderedDict , иначе вы можете просто использовать обычный dict .
Дамп / загрузка Json
Что касается json.dump
, это другой вопрос:
Насколько я могу судить, JSONEncoder
итерации по ключам, поэтому порядок не должен меняться.
Вы можете принудительно установить лексикографический порядок, если хотите:
>>> json.dumps({'b': 1, 'a': 2}, sort_keys=True)
'{"a": 2, "b": 1}'
Что касается загрузки, я не понимаю, почему порядок не будет сохранен, но я признаю, что теряюсь в исходном коде для декодера и сканера.
Если вы хотите, вы можете использовать:
>>> json.loads('{"b": 2, "a": 1}', object_pairs_hook=OrderedDict)
OrderedDict([('b', 2), ('a', 1)])
Вложенные dicts
Вышесказанное применимо и к вложенным dicts: _iterencode_dict
вызывается рекурсивно, и ключи сортируются для всех dicts.
Действительно:
>>> json.dumps({'b': 1, 'a': {'d': 1, 'c': 3}}, sort_keys=True)
'{"a": {"c": 3, "d": 1}, "b": 1}'
Приветствия!
Комментарии:
1.
Json.dumps
sort_keys будет работать, только если у нас есть dict, не так ли? В моем случае у меня есть вложенный dict, так что это не сработает правильно? Поскольку sort_keys сортирует только внешние ключи. Если вы видите пример данных, которые я привел выше, это тот тип данных, который у меня есть2. @user_12 нет, он сортирует ключи всех объектов JSON
3. Я добавил раздел, касающийся вложенных dicts, он будет рекурсивно сортировать ключи.
4. @juanpa.arrivillaga Понял, тогда я могу безопасно использовать sort_keys всякий раз, когда я использую дамп или загрузку. Это полезно
5. Дополнительное (возможное) преимущество по
OrderedDict
сравнению с обычными обычнымиdict
:OrderedDict
тесты на равенство при сравнении с другимиOrderedDict
зависят от порядка.dict
нет (dict == dict
илиdict == OrderedDict
илиOrderedDict == dict
не зависит от порядка, но чувствителен к порядкуOrderedDict == OrderedDict
; если порядок ключей не совпадает, он не будет равен).