Saya perlu membandingkan dua daftar untuk membuat daftar baru dari elemen spesifik yang ditemukan di satu daftar tetapi tidak di daftar lainnya. Sebagai contoh:
main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
Saya ingin mengulang list_1 dan menambahkan ke main_list semua elemen dari list_2 yang tidak ditemukan di list_1.
Hasilnya seharusnya:
main_list=["f", "m"]
Bagaimana saya bisa melakukannya dengan python?
list_2
yang tidak muncul di tempatlist_1
atau elemenlist_2
yang tidak ada di indeks yang samalist_1
?Jawaban:
TL; DR:
SOLUSI (1)
SOLUSI (2) Anda menginginkan daftar yang diurutkan
PENJELASAN:
(1) Anda dapat menggunakan NumPy ini
setdiff1d
(array1
,array2
,assume_unique
=False
).assume_unique
meminta pengguna JIKA array SUDAH UNIK.Jika
False
, maka elemen uniknya ditentukan terlebih dahulu.Jika
True
, fungsi akan menganggap bahwa elemen tersebut sudah unik DAN fungsi akan melewatkan penentuan elemen unik.Ini menghasilkan nilai unik
array1
yang tidak ada di dalamnyaarray2
.assume_unique
adalahFalse
secara default.Jika Anda khawatir dengan elemen unik (berdasarkan respons Chinny84 ), maka cukup gunakan (di mana
assume_unique=False
=> nilai default):(2) Bagi mereka yang ingin jawaban diurutkan, saya telah membuat fungsi khusus:
Untuk mendapatkan jawabannya, jalankan:
CATATAN SAMPING:
(a) Solusi 2 (fungsi kustom
setdiff_sorted
) mengembalikan daftar (dibandingkan dengan array dalam solusi 1).(b) Jika Anda tidak yakin apakah elemennya unik, cukup gunakan pengaturan default NumPy
setdiff1d
di kedua solusi A dan B. Apa yang bisa menjadi contoh komplikasi? Lihat catatan (c).(c) Hal-hal akan berbeda jika salah satu dari dua daftar tersebut tidak unik.
Katakanlah
list_2
tidak unik:list2 = ["a", "f", "c", "m", "m"]
. Pertahankanlist1
apa adanya:list_1 = ["a", "b", "c", "d", "e"]
Menyetel nilai default
assume_unique
hasil["f", "m"]
(di kedua solusi). NAMUN, jika Anda menetapkanassume_unique=True
, kedua solusi memberikan["f", "m", "m"]
. Mengapa? Ini karena pengguna MENGANGGAP bahwa elemennya unik). Karenanya, LEBIH BAIK UNTUK DIPERTAHANKANassume_unique
ke nilai defaultnya. Perhatikan bahwa kedua jawaban diurutkan.pythonnumpy
sumber
Anda dapat menggunakan set:
Keluaran:
Sesuai komentar @JonClements, berikut adalah versi yang lebih rapi:
sumber
unique
elemen tetapi bagaimana jika kita memiliki banyakm's
misalnya ini tidak akan mengambilnya.list(set(list_2).difference(list_1))
menghindariset
konversi eksplisit ...Tidak yakin mengapa penjelasan di atas begitu rumit ketika Anda memiliki metode asli yang tersedia:
sumber
Gunakan pemahaman daftar seperti ini:
Keluaran:
Edit:
Seperti yang disebutkan dalam komentar di bawah, dengan daftar besar, di atas bukanlah solusi ideal. Jika demikian, opsi yang lebih baik adalah mengonversi
list_1
menjadi yangset
pertama:sumber
list_1
, Anda ingin mengkonversikan sebelumnya keset
/frozenset
, misalnyaset_1 = frozenset(list_1)
, kemudianmain_list = [item for item in list_2 if item not in set_1]
, mengurangi waktu pemeriksaan dariO(n)
per item menjadi (secara kasar)O(1)
.enumerate()
untuk itu:[index for (index, item) in enumerate(list_2) if item not in list_1]
Jika Anda ingin solusi satu-kapal (mengabaikan impor) yang hanya membutuhkan
O(max(n, m))
pekerjaan untuk input panjangn
danm
, tidakO(n * m)
bekerja, Anda dapat melakukannya dengan paraitertools
modul :Ini memanfaatkan fungsi fungsional yang mengambil fungsi callback pada konstruksi, yang memungkinkannya membuat callback sekali dan menggunakannya kembali untuk setiap elemen tanpa perlu menyimpannya di suatu tempat (karena
filterfalse
menyimpannya secara internal); pemahaman daftar dan ekspresi generator bisa melakukan ini, tapi itu jelek. †Itu mendapatkan hasil yang sama dalam satu baris seperti:
dengan kecepatan:
Tentu saja, jika perbandingan dimaksudkan untuk menjadi posisi, maka:
harus menghasilkan:
(karena nilai dalam
list_2
memiliki kecocokan pada indeks yang sama dilist_1
), Anda harus menggunakan jawaban Patrick , yang tidak melibatkanlist
s atau s sementaraset
(bahkan denganset
s secara kasarO(1)
, mereka memiliki faktor "konstan" yang lebih tinggi per cek daripada pemeriksaan persamaan sederhana ) dan melibatkanO(min(n, m))
pekerjaan, kurang dari jawaban lain, dan jika masalah Anda sensitif terhadap posisi, adalah satu-satunya solusi yang tepat saat elemen yang cocok muncul di offset yang tidak cocok.†: Cara melakukan hal yang sama dengan pemahaman daftar sebagai satu-liner akan menyalahgunakan perulangan bersarang untuk membuat dan nilai cache di loop "terluar", misalnya:
yang juga memberikan keuntungan kinerja kecil pada Python 3 (karena sekarang
set_1
dicakup secara lokal dalam kode pemahaman, daripada mencari dari lingkup bersarang untuk setiap pemeriksaan; pada Python 2 itu tidak masalah, karena Python 2 tidak menggunakan penutup untuk daftar pemahaman; mereka beroperasi dalam lingkup yang sama dengan yang mereka gunakan).sumber
keluaran:
sumber
list_1
besar, danlist_2
berukuran tidak sepele, karena melibatkanlen(list_2)
O(n)
pemindaianlist_1
, membuatnyaO(n * m)
(di manan
danm
adalah panjanglist_2
danlist_1
masing - masing). Jika Anda mengonversilist_1
ke aset
/frozenset
di depan, pemeriksaan berisi dapat dilakukan diO(1)
, membuat total pekerjaanO(n)
pada panjanglist_2
(secara teknisO(max(n, m))
, karena AndaO(m)
bekerja untuk membuatnyaset
).Saya akan
zip
membuat daftar bersama untuk membandingkannya elemen demi elemen.sumber
list
dengan satu yang barulist
sedang dibangun, tidak ada temporer tambahan , tidak ada pemeriksaan penahanan yang mahal, dll.Saya menggunakan dua metode dan saya menemukan satu metode berguna di atas yang lain. Inilah jawaban saya:
Data masukan saya:
Metode 1:
np.setdiff1d
Saya menyukai pendekatan ini daripada yang lain karena ini mempertahankan posisinyaMetode2: Meskipun memberikan jawaban yang sama seperti di Metode1 tetapi mengganggu urutan
Method1
np.setdiff1d
memenuhi persyaratan saya dengan sempurna. Jawaban ini untuk informasi.sumber
Jika jumlah kejadian harus diperhitungkan, Anda mungkin perlu menggunakan sesuatu seperti
collections.Counter
:Seperti yang dijanjikan, ini juga dapat menangani jumlah kemunculan yang berbeda sebagai "perbedaan":
sumber
Dari ser1 hapus item yang ada di ser2.
Memasukkan
ser1 = pd. Seri ([1, 2, 3, 4, 5]) ser2 = pd. Seri ([4, 5, 6, 7, 8])
Larutan
ser1 [~ ser1.isin (ser2)]
sumber