Untuk banyak kasus penggunaan, jawaban yang Anda inginkan adalah:
ys = set(y)
[item for item in x if item not in ys]
Ini adalah gabungan antara jawaban aaronasterling dan jawaban quantumSoup .
Versi aaronasterling melakukan len(y)
perbandingan item untuk setiap elemen x
, sehingga dibutuhkan waktu kuadratik. Versi quantumSoup menggunakan set, sehingga ia melakukan pencarian set waktu konstan tunggal untuk setiap elemen dalam x
—tapi, karena ia mengubah keduanya x
dan y
menjadi set, ia kehilangan urutan elemen Anda.
Dengan mengubah hanya y
menjadi satu set, dan mengulanginya x
secara berurutan, Anda mendapatkan yang terbaik dari kedua dunia — waktu linier, dan pelestarian pesanan. *
Namun, ini masih memiliki masalah dari versi quantumSoup: Ini membutuhkan elemen Anda untuk dapat hashable. Itu cukup banyak dibangun ke dalam sifat set. ** Jika Anda mencoba, misalnya, kurangi daftar dicts dari daftar dicts lain, tetapi daftar untuk mengurangi besar, apa yang Anda lakukan?
Jika Anda dapat menghias nilai-nilai Anda dengan cara yang dapat di-hashable, itu memecahkan masalah. Misalnya, dengan kamus datar yang nilainya sendiri dapat diunggah:
ys = {tuple(item.items()) for item in y}
[item for item in x if tuple(item.items()) not in ys]
Jika tipe Anda sedikit lebih rumit (misalnya, sering Anda berurusan dengan nilai yang kompatibel dengan JSON, yang dapat hashable, atau daftar atau dikte yang nilainya secara rekursif adalah jenis yang sama), Anda masih dapat menggunakan solusi ini. Tetapi beberapa tipe tidak dapat dikonversi menjadi hashable apa pun.
Jika barang Anda tidak, dan tidak dapat dibuat, dapat hashable, tetapi mereka dapat dibandingkan, Anda setidaknya bisa mendapatkan waktu log-linear ( O(N*log M)
, yang jauh lebih baik daripada O(N*M)
waktu solusi daftar, tetapi tidak sebagus yang O(N+M)
saat solusi set) dengan menyortir dan menggunakan bisect
:
ys = sorted(y)
def bisect_contains(seq, item):
index = bisect.bisect(seq, item)
return index < len(seq) and seq[index] == item
[item for item in x if bisect_contains(ys, item)]
Jika barang Anda tidak dapat dipilah atau sebanding, maka Anda terjebak dengan solusi kuadratik.
* Perhatikan bahwa Anda juga bisa melakukan ini dengan menggunakan sepasang OrderedSet
benda, yang untuknya Anda dapat menemukan resep dan modul pihak ketiga. Tapi saya pikir ini lebih sederhana.
** Alasan set lookup adalah waktu yang konstan adalah yang harus dilakukan hanyalah nilai hash dan lihat apakah ada entri untuk hash itu. Jika tidak dapat mengaitkan nilainya, ini tidak akan berhasil.