Как я могу проверить, равны ли два объекта JSON в python, не обращая внимания на порядок списков?
Например ...
Документ JSON a :
{
"errors": [
{"error": "invalid", "field": "email"},
{"error": "required", "field": "name"}
],
"success": false
}
Документ JSON b :
{
"success": false,
"errors": [
{"error": "required", "field": "name"},
{"error": "invalid", "field": "email"}
]
}
a
и b
должны сравниваться одинаково, даже если порядок в "errors"
списках разный.
python
json
django
comparison
Петтер Фриберг
источник
источник
list
элементов тоже не имеет значения?Ответы:
Если вы хотите, чтобы два объекта с одинаковыми элементами, но в разном порядке сравнивали равные, то очевидное дело - сравнить их отсортированные копии - например, для словарей, представленных вашими строками JSON
a
иb
:... но это не работает, потому что в каждом случае
"errors"
элемент dict верхнего уровня представляет собой список с одинаковыми элементами в другом порядке иsorted()
не пытается отсортировать что-либо, кроме «верхнего» уровня итеративный.Чтобы исправить это, мы можем определить
ordered
функцию, которая будет рекурсивно сортировать любые найденные списки (и преобразовывать словари в списки(key, value)
пар, чтобы их можно было заказать):Если мы применим эту функцию к
a
иb
, результаты будут равны:источник
['astr', {'adict': 'something'}]
, я получилTypeError
при попытке их отсортировать.Другой способ - использовать
json.dumps(X, sort_keys=True)
опцию:Это работает для вложенных словарей и списков.
источник
{"error":"a"}, {"error":"b"}
против,{"error":"b"}, {"error":"a"}
он не сможет отсортировать последний случай в первый случайjson.dumps({'foo': [3, 1, 2]}, sort_keys=True) == json.dumps({'foo': [2, 1, 3]}, sort_keys=True)
Расшифруйте их и сравните как комментарий mgilson.
Порядок не имеет значения для словаря, пока ключи и значения совпадают. (Словарь не имеет порядка в Python)
Но порядок важен в списке; сортировка решит проблему для списков.
Приведенный выше пример будет работать для JSON в вопросе. Для общего решения см. Ответ Zero Piraeus.
источник
Для следующих двух dictWithListsInValue и reorderedDictWithReorderedListsInValue, которые представляют собой просто переупорядоченные версии друг друга.
дал мне неправильный результат, т.е. ложный.
Итак, я создал свой собственный компаратор объектов Cutstom вот так:
что дало мне правильный ожидаемый результат!
Логика довольно проста:
Если объекты относятся к типу «список», тогда сравнивайте каждый элемент первого списка с элементами второго списка до тех пор, пока он не будет найден, и если элемент не будет найден после просмотра второго списка, тогда «найденный» будет = false. возвращается значение 'found'
В противном случае, если сравниваемые объекты относятся к типу «dict», сравните значения, представленные для всех соответствующих ключей в обоих объектах. (Выполняется рекурсивное сравнение)
В противном случае просто вызовите obj1 == obj2. По умолчанию он отлично работает для объекта строк и чисел, и для них eq () определен соответствующим образом.
(Обратите внимание, что алгоритм можно дополнительно улучшить, удалив элементы, найденные в объекте 2, чтобы следующий элемент объекта 1 не сравнивался с элементами, уже найденными в объекте 2)
источник
Вы можете написать свою собственную функцию равенства:
a == b
Потому что вы имеете дело с JSON, вы будете иметь стандартные типы питона:
dict
,list
и т.д., так что вы можете сделать жесткий контроль типовif type(obj) == 'dict':
и т.д.Примерный пример (не тестировался):
источник
Для тех, кто хочет отладить два объекта JSON (обычно это ссылка и цель ), вот решение, которое вы можете использовать. Он перечислит « путь » разных / несовпадающих от цели к ссылке.
level
Опция используется для выбора того, насколько глубоко вы хотите заглянуть.show_variables
можно включить опцию, чтобы отобразить соответствующую переменную.источник