Misalkan saya memiliki dua kamus Python - dictA
dan dictB
. Saya perlu mencari tahu apakah ada kunci yang ada dictB
tetapi tidak di dictA
. Apa cara tercepat untuk melakukannya?
Haruskah saya mengubah kunci kamus menjadi satu set dan kemudian melanjutkan?
Tertarik mengetahui pemikiran Anda ...
Terima kasih atas tanggapan Anda.
Permintaan maaf karena tidak menyatakan pertanyaan saya dengan benar. Skenario saya adalah seperti ini - Saya memiliki dictA
yang dapat sama dictB
atau mungkin memiliki beberapa kunci yang hilang dibandingkan dengan dictB
atau nilai beberapa kunci mungkin berbeda yang harus ditetapkan dengan dictA
nilai kunci.
Masalahnya adalah kamus tidak memiliki standar dan dapat memiliki nilai yang dapat berupa dikt.
Mengatakan
dictA={'key1':a, 'key2':b, 'key3':{'key11':cc, 'key12':dd}, 'key4':{'key111':{....}}}
dictB={'key1':a, 'key2:':newb, 'key3':{'key11':cc, 'key12':newdd, 'key13':ee}.......
Jadi nilai 'key2' harus diatur ulang ke nilai baru dan 'key13' harus ditambahkan di dalam dikt. Nilai kunci tidak memiliki format tetap. Ini bisa berupa nilai sederhana atau dict atau dict.
sumber
def update(self, new_dict): self.__init__(new_dict, self.current_dict)
dengan sejenisnya sehingga Anda dapat melakukan perbandingan bergulirDictDiffer
kelas adalah kelas tanpa kewarganegaraan dan bisa menjadi fungsi. Nilaichanged
danunchanged
dapat dihitung dalam loop yang sama. Kedua fungsi ini bisa mengembalikan yanglist
bukanset
yang tentu saja lebih murah. Untuk perbandingan mendalam, Anda dapat melihat kerangka pengujian Unit: docs.python.org/2/library/unittest.html , cukup ikutiassertDictEqual
metode dalam kode sumber.set(dictb)
mungkin lebih baik daripadaset(dictb.keys())
.Jika Anda ingin perbedaannya secara berulang, saya telah menulis paket untuk python: https://github.com/seperman/deepdiff
Instalasi
Instal dari PyPi:
Contoh penggunaan
Pengimporan
Objek yang sama kembali kosong
Jenis item telah berubah
Nilai suatu barang telah berubah
Item ditambahkan dan / atau dihapus
Perbedaan string
Perbedaan string 2
Ketik perubahan
Daftar perbedaan
Daftar perbedaan 2:
Daftar perbedaan dengan mengabaikan urutan atau duplikat: (dengan kamus yang sama seperti di atas)
Daftar yang berisi kamus:
Set:
Dinamai Tuples:
Objek khusus:
Atribut objek ditambahkan:
sumber
ignore_order=True
. Anda dapat menemukan dokumen di deepdiff.readthedocs.io/en/latest/diff.htmltidak yakin apakah itu "cepat" atau tidak, tetapi biasanya, orang bisa melakukan ini
sumber
dicta
dandictb
karena dia ingin tahu kunci-kuncidictb
yang tidak masukdicta
.for key in dicta.keys():
=>for key in dicta:
Seperti yang ditulis Alex Martelli, jika Anda hanya ingin memeriksa apakah ada kunci dalam B tidak dalam A,
any(True for k in dictB if k not in dictA)
akan menjadi cara untuk pergi.Untuk menemukan kunci yang hilang:
Jadi kedua solusi itu memiliki kecepatan yang hampir sama.
sumber
any(k not in dictA for k in dictB)
Jika Anda benar-benar memaksudkan apa yang Anda katakan (bahwa Anda hanya perlu mencari tahu JIKA "ada kunci" dalam B dan tidak dalam A, bukan YANG MENGHASILKAN jika ada), cara tercepat adalah:
Jika Anda benar-benar perlu mencari tahu KUNCI YANG, jika ada, dalam B dan tidak dalam A, dan bukan hanya "JIKA" ada kunci seperti itu, maka jawaban yang ada cukup tepat (tapi saya sarankan lebih presisi dalam pertanyaan di masa depan jika itu memang apa yang Anda maksud ;-).
sumber
Gunakan
set()
:sumber
set(d)
sudah mengembalikan hanya kunci, sehingga Anda dapat melakukannyaset(da).intersection(db)
Jawaban teratas oleh hughdbrown menyarankan menggunakan perbedaan set, yang jelas merupakan pendekatan terbaik:
Masalah dengan kode ini adalah bahwa ia membangun dua daftar hanya untuk membuat dua set, sehingga membuang waktu 4N dan ruang 2N. Ini juga sedikit lebih rumit dari yang seharusnya.
Biasanya, ini bukan masalah besar, tetapi jika:
collections.abc.Mapping
memilikiKeysView
yang bertindak sepertiSet
.Python 2
Dalam Python 2,
keys()
mengembalikan daftar kunci, bukan aKeysView
. Jadi, Anda harus memintaviewkeys()
secara langsung.Untuk kode dual-versi 2.7 / 3.x, mudah-mudahan Anda menggunakan
six
atau sesuatu yang serupa, sehingga Anda dapat menggunakansix.viewkeys(dictb)
:Di 2.4-2.6, tidak ada
KeysView
. Tetapi Anda setidaknya dapat memotong biaya dari 4N ke N dengan membangun set kiri Anda langsung dari iterator, daripada membangun daftar terlebih dahulu:Item
Jadi Anda benar-benar tidak perlu membandingkan kunci, tetapi item. An
ItemsView
hanya aSet
jika nilainya hashable, seperti string. Jika ya, mudah:Perbedaan rekursif
Meskipun pertanyaannya tidak secara langsung menanyakan perbedaan rekursif, beberapa nilai contohnya adalah dicts, dan tampaknya output yang diharapkan memang berbeda secara rekursif. Sudah ada beberapa jawaban di sini yang menunjukkan cara melakukannya.
sumber
Ada pertanyaan lain dalam stackoverflow tentang argumen ini dan saya harus mengakui bahwa ada solusi sederhana yang dijelaskan: pustaka data python membantu mencetak perbedaan antara dua kamus.
sumber
Inilah cara yang akan bekerja, memungkinkan kunci yang dievaluasi
False
, dan masih menggunakan ekspresi generator untuk keluar lebih awal jika memungkinkan. Ini tidak terlalu cantik.EDIT:
THC4k mengirim balasan ke komentar saya pada jawaban lain. Inilah cara yang lebih baik dan lebih cantik untuk melakukan hal di atas:
Tidak yakin bagaimana itu tidak pernah terlintas dalam pikiran saya ...
sumber
any(k for k in dictB if k not in dictA)
yang bukan hal yang sama (untuk kunci falsey). Periksa riwayat edit / cap waktu.Ini adalah pertanyaan lama dan meminta sedikit lebih sedikit dari yang saya butuhkan sehingga jawaban ini benar-benar memecahkan lebih dari pertanyaan ini. Jawaban dalam pertanyaan ini membantu saya memecahkan yang berikut:
Semua ini dikombinasikan dengan JSON membuat dukungan penyimpanan konfigurasi yang cukup kuat.
Solusinya ( juga di github ):
sumber
bagaimana dengan standar (bandingkan Objek LENGKAP)
PyDev-> new PyDev Module-> Module: unittest
sumber
Jika menggunakan Python ≥ 2.7:
sumber
Berikut adalah solusi untuk membandingkan 2 kunci kamus:
sumber
inilah solusi yang dapat membandingkan lebih dari dua dicts:
contoh penggunaan:
sumber
Resep saya tentang perbedaan simetris antara dua kamus:
Dan hasilnya adalah:
sumber
Seperti disebutkan dalam jawaban lain, unittest menghasilkan beberapa output yang bagus untuk membandingkan dicts, tetapi dalam contoh ini kita tidak ingin harus membangun seluruh tes terlebih dahulu.
Menggores sumber yang tidak terdaftar, sepertinya Anda bisa mendapatkan solusi yang adil hanya dengan ini:
begitu
Hasil dalam:
Dimana:
Seperti di unittest, satu-satunya peringatan adalah bahwa pemetaan akhir dapat dianggap berbeda, karena koma / braket trailing.
sumber
@ Maxx memiliki jawaban yang sangat baik, gunakan
unittest
alat yang disediakan oleh Python:Lalu, di mana pun dalam kode Anda, Anda dapat menelepon:
Output yang dihasilkan terlihat seperti output dari
diff
, cukup mencetak kamus dengan+
atau-
menambahkan setiap baris yang berbeda.sumber
Tidak yakin apakah itu masih relevan tetapi saya menemukan masalah ini, situasi saya, saya hanya perlu mengembalikan kamus kamus untuk semua kamus bersarang dll. Tidak dapat menemukan solusi yang baik di luar sana tetapi pada akhirnya saya menulis fungsi sederhana untuk melakukan ini . Semoga ini membantu,
sumber
Jika Anda menginginkan solusi bawaan untuk perbandingan penuh dengan struktur dikt sembarang, jawaban @ Maxx adalah awal yang baik.
sumber
Berdasarkan jawaban ghostdog74,
akan mencetak nilai dicta yang berbeda
sumber
Coba ini untuk menemukan de persimpangan, kunci yang ada di kedua dictionarie, jika Anda ingin tombol tidak ditemukan di dictionarie kedua, cukup gunakan tidak di ...
sumber