a = [1, 2, 3, 1, 2, 3]
b = [3, 2, 1, 3, 2, 1]
a & b harus dianggap sama, karena mereka memiliki elemen yang persis sama, hanya dalam urutan yang berbeda.
Masalahnya, daftar aktual saya akan terdiri dari objek (instance kelas saya), bukan bilangan bulat.
python
algorithm
list
comparison
johndir
sumber
sumber
len()
dulu.Jawaban:
O (n) : Metode Penghitung () adalah yang terbaik (jika objek Anda hashable):
O (n log n) : Metode diurutkan () adalah yang terbaik berikutnya (jika objek Anda dapat dipesan):
O (n * n) : Jika objek tidak hashable atau orderable, Anda dapat menggunakan persamaan:
sumber
sorted()
, diakui tidak tahu tentangCounter
. Pewawancara bersikeras ada metode yang lebih efisien dan jelas saya menarik kosong. Setelah pengujian ekstensif dalam python 3 dengantimeit
modul, diurutkan secara konsisten keluar lebih cepat pada daftar bilangan bulat. Pada daftar, item 1k, sekitar 1,5% lebih lambat dan pada daftar pendek, 10 item, 7,5% lebih lambat. Pikiran?python3.6 -m timeit -s 'from collections import Counter' -s 'from random import shuffle' -s 't=list(range(100)) * 5' -s 'shuffle(t)' -s 'u=t[:]' -s 'shuffle(u)' 'Counter(t)==Counter(u)'
sorted vs counter
.. Saya sangat ingin tahu apa yang terjadi di sini.Anda dapat mengurutkan keduanya:
Sebuah penghitungan semacam juga bisa menjadi lebih efisien (tetapi membutuhkan objek menjadi hashable).
sumber
__hash__
, tapi itu mungkin mustahil untuk koleksi.sorted([0, 1j])
Jika Anda tahu item selalu hashable, Anda dapat menggunakan
Counter()
yang O (n)Jika Anda tahu item selalu diurutkan, Anda dapat menggunakan
sorted()
yang O (n log n)Dalam kasus umum, Anda tidak dapat mengandalkan kemampuan untuk menyortir, atau memiliki elemen, sehingga Anda perlu mundur seperti ini, yang sayangnya O (n ^ 2)
sumber
Cara terbaik untuk melakukan ini adalah dengan menyortir daftar dan membandingkannya. (Menggunakan
Counter
tidak akan bekerja dengan objek yang tidak hash.) Ini mudah untuk integer:Itu menjadi sedikit rumit dengan benda-benda sewenang-wenang. Jika Anda peduli tentang identitas objek, yaitu apakah objek yang sama ada di kedua daftar, Anda dapat menggunakan
id()
fungsi sebagai kunci pengurutan.(Dalam Python 2.x Anda sebenarnya tidak memerlukannya
key=
parameter, karena Anda dapat membandingkan objek apa pun dengan objek apa pun. Urutannya arbitrer tetapi stabil, sehingga berfungsi dengan baik untuk tujuan ini; tidak masalah apa pun urutan objeknya di, hanya bahwa urutannya sama untuk kedua daftar. Dalam Python 3, meskipun, membandingkan objek dari berbagai jenis tidak diizinkan dalam banyak keadaan - misalnya, Anda tidak dapat membandingkan string dengan bilangan bulat - jadi jika Anda akan memiliki objek dari berbagai jenis, terbaik untuk secara eksplisit menggunakan ID objek.)Jika Anda ingin membandingkan objek dalam daftar dengan nilai, di sisi lain, pertama-tama Anda perlu mendefinisikan apa arti "nilai" untuk objek. Maka Anda akan memerlukan beberapa cara untuk menyediakannya sebagai kunci (dan untuk Python 3, sebagai jenis yang konsisten). Salah satu cara potensial yang akan bekerja untuk banyak objek sewenang-wenang adalah mengurutkannya
repr()
. Tentu saja, ini bisa membuang banyak waktu ekstra danrepr()
string pembangun memori untuk daftar besar dan sebagainya.Jika objek adalah semua tipe Anda sendiri, Anda bisa mendefinisikannya
__lt__()
agar objek tahu bagaimana membandingkan dirinya dengan orang lain. Maka Anda bisa menyortirnya dan tidak khawatir tentangkey=
parameternya. Tentu saja Anda juga bisa mendefinisikan__hash__()
dan menggunakanCounter
, yang akan lebih cepat.sumber
https://docs.python.org/3.5/library/unittest.html#unittest.TestCase.assertCountEqual
assertCountEqual (pertama, kedua, msg = Tidak Ada)
Uji bahwa urutan pertama mengandung elemen yang sama dengan yang kedua, terlepas dari urutannya. Ketika tidak, pesan kesalahan yang mencantumkan perbedaan antara urutan akan dihasilkan.
Elemen duplikat tidak diabaikan ketika membandingkan pertama dan kedua. Itu memverifikasi apakah setiap elemen memiliki jumlah yang sama di kedua urutan. Setara dengan: assertEqual (Penghitung (daftar (pertama)), Penghitung (daftar (kedua))) tetapi bekerja dengan urutan objek yang tidak dapat dihancurkan juga.
Baru dalam versi 3.2.
atau di 2.7: https://docs.python.org/2.7/library/unittest.html#unittest.TestCase.assertItemsEqual
sumber
Jika daftar berisi item yang tidak hashable (seperti daftar objek), Anda mungkin dapat menggunakan kelas penghitung dan fungsi id () seperti:
sumber
Saya harap potongan kode di bawah ini dapat berfungsi dalam kasus Anda: -
Ini akan memastikan bahwa semua elemen dalam daftar
a
&b
sama, terlepas dari apakah mereka berada dalam urutan yang sama atau tidak.Untuk pemahaman yang lebih baik, lihat jawaban saya di pertanyaan ini
sumber
Jika perbandingan akan dilakukan dalam konteks pengujian, gunakan
assertCountEqual(a, b)
(py>=3.2
) danassertItemsEqual(a, b)
(2.7<=py<3.2
).Berfungsi pada urutan objek yang tidak dapat dihancurkan juga.
sumber
Biarkan a, b daftar
Tidak perlu membuatnya hashable atau mengurutkannya.
sumber
a
dukunganpop
(dapat diubah) danindex
(adalah urutan). Raymond tidak berasumsi sementara gnibbler hanya mengasumsikan urutan.Menggunakan
unittest
modul memberi Anda pendekatan yang bersih dan standar.sumber