Bagaimana saya dapat menguji apakah dua objek JSON sama dengan python, mengabaikan urutan daftar?
Sebagai contoh ...
JSON dokumen a :
{
"errors": [
{"error": "invalid", "field": "email"},
{"error": "required", "field": "name"}
],
"success": false
}
Dokumen JSON b :
{
"success": false,
"errors": [
{"error": "required", "field": "name"},
{"error": "invalid", "field": "email"}
]
}
a
dan b
harus membandingkan sama, meskipun urutan "errors"
daftarnya berbeda.
python
json
django
comparison
Petter Friberg
sumber
sumber
list
elemen tidak penting?Jawaban:
Jika Anda menginginkan dua objek dengan elemen yang sama tetapi dalam urutan berbeda untuk membandingkan sama, maka hal yang harus dilakukan adalah membandingkan salinan yang diurutkan dari mereka - misalnya, untuk kamus yang diwakili oleh string JSON Anda
a
danb
:... tetapi itu tidak berhasil, karena dalam setiap kasus,
"errors"
item dari dict level teratas adalah daftar dengan elemen yang sama dalam urutan berbeda, dansorted()
tidak mencoba untuk mengurutkan apa pun kecuali level "teratas" dari sebuah iterable.Untuk memperbaikinya, kita dapat mendefinisikan sebuah
ordered
fungsi yang secara rekursif akan mengurutkan daftar apa pun yang ditemukannya (dan mengonversi kamus menjadi daftar(key, value)
pasangan sehingga dapat diurutkan):Jika kita menerapkan fungsi ini ke
a
danb
, hasilnya sebanding:sumber
['astr', {'adict': 'something'}]
, saya dapatkanTypeError
saat mencoba menyortirnya.Cara lain bisa menggunakan
json.dumps(X, sort_keys=True)
opsi:Ini berfungsi untuk kamus dan daftar bertingkat.
sumber
{"error":"a"}, {"error":"b"}
vs{"error":"b"}, {"error":"a"}
tidak akan dapat mengurutkan kasus terakhir menjadi kasus pertamajson.dumps({'foo': [3, 1, 2]}, sort_keys=True) == json.dumps({'foo': [2, 1, 3]}, sort_keys=True)
Pecahkan kodenya dan bandingkan sebagai komentar mgilson.
Urutan tidak menjadi masalah bagi kamus selama kunci, dan nilainya cocok. (Kamus tidak memiliki urutan dengan Python)
Tetapi urutan penting dalam daftar; penyortiran akan menyelesaikan masalah untuk daftar.
Contoh di atas akan berfungsi untuk JSON dalam pertanyaan. Untuk solusi umum, lihat jawaban Zero Piraeus.
sumber
Untuk dua dicts berikut 'dictWithListsInValue' dan 'reorderedDictWithReorderedListsInValue' yang merupakan versi yang disusun ulang satu sama lain
memberi saya hasil yang salah yaitu salah.
Jadi saya membuat ObjectComparator cutstom saya sendiri seperti ini:
yang memberi saya hasil yang diharapkan benar!
Logikanya cukup sederhana:
Jika objek bertipe 'list' maka bandingkan setiap item dari list pertama dengan item dari list kedua hingga ditemukan, dan jika item tersebut tidak ditemukan setelah melalui list kedua, maka 'found' akan menjadi = false. nilai 'ditemukan' dikembalikan
Lain jika objek yang akan dibandingkan adalah tipe 'dict' kemudian bandingkan nilai-nilai yang ada untuk semua kunci masing-masing di kedua objek. (Perbandingan rekursif dilakukan)
Lain cukup panggil obj1 == obj2. Ini secara default berfungsi dengan baik untuk objek string dan angka dan untuk eq () itu didefinisikan dengan tepat.
(Perhatikan bahwa algoritme selanjutnya dapat ditingkatkan dengan menghapus item yang ditemukan di objek2, sehingga item objek1 berikutnya tidak akan membandingkan dirinya sendiri dengan item yang sudah ditemukan di objek2)
sumber
Anda dapat menulis fungsi sama dengan Anda sendiri:
a == b
Karena Anda sedang berhadapan dengan json, Anda akan memiliki jenis python standar:
dict
,list
, dll, sehingga Anda dapat melakukan pengecekan jenis hardif type(obj) == 'dict':
, dllContoh kasar (tidak diuji):
sumber
Bagi orang lain yang ingin men-debug dua objek JSON (biasanya, ada referensi dan target ), berikut adalah solusi yang dapat Anda gunakan. Ini akan mencantumkan " jalur " yang berbeda / tidak cocok dari target ke referensi.
level
opsi digunakan untuk memilih seberapa dalam Anda ingin melihat.show_variables
opsi dapat diaktifkan untuk menunjukkan variabel yang relevan.sumber