Menghapus duplikat dalam daftar
Cukup banyak yang saya butuhkan untuk menulis sebuah program untuk memeriksa jika daftar telah duplikat dan jika itu tidak menghilangkan mereka dan kembali baru daftar dengan item yang tidak't digandakan/dihapus. Ini adalah apa yang saya miliki tapi jujur saya tidak tahu apa yang harus dilakukan.
def remove_duplicates():
t = ['a', 'b', 'c', 'd']
t2 = ['a', 'c', 'd']
for t in t2:
t.append(t.remove())
return t
871
47
Pendekatan yang umum untuk mendapatkan koleksi unik dari barang-barang adalah dengan menggunakan
set
. Set unordered koleksi berbeda benda-benda. Untuk membuat satu set dari setiap iterable, anda hanya dapat menyebarkannya ke built-inset()
fungsi. Jika anda kemudian perlu daftar lagi, anda dapat pula lulus diatur kedaftar()
fungsi.Contoh berikut harus mencakup apa pun yang anda coba lakukan:
Seperti yang anda lihat dari contoh hasil, asli agar tidak dipertahankan. Seperti disebutkan di atas, set sendiri adalah unordered koleksi, sehingga urutan hilang. Ketika mengkonversi satu set kembali ke daftar, urutan sewenang-wenang dibuat.
Menjaga ketertiban
Jika urutan ini penting untuk anda, maka anda akan harus menggunakan mekanisme yang berbeda. Yang sangat umum solusi untuk ini adalah untuk mengandalkan
OrderedDict
untuk menjaga urutan tombol selama penyisipan:Mulai dengan Python 3.7, built-in kamus dijamin untuk menjaga penyisipan order juga, sehingga anda juga dapat menggunakannya secara langsung jika anda berada di Python 3.7 atau lambat (atau CPython 3.6):
Catatan ini telah overhead membuat kamus pertama, dan kemudian membuat daftar dari itu. Jika anda tidak benar-benar perlu untuk menjaga ketertiban, anda lebih baik menggunakan satu set. Check out pertanyaan untuk rincian lebih lanjut dan cara-cara alternatif untuk menjaga agar ketika menghapus duplikat.
Akhirnya diketahui bahwa kedua
set
sertaOrderedDict
/dict
solusi membutuhkan barang-barang anda untuk menjadi hashable. Hal ini biasanya berarti bahwa mereka harus berubah. Jika anda memiliki untuk berurusan dengan barang-barang yang tidak hashable (misalnya daftar benda-benda), maka anda akan harus menggunakan pendekatan lambat di mana anda pada dasarnya akan memiliki untuk membandingkan setiap item dengan setiap item dalam nested loop.Di Python 2.7, cara baru menghapus duplikat dari iterable sambil menjaga dalam urutan asli adalah:
Di Python 3.5, yang OrderedDict memiliki implementasi C. Saya timing menunjukkan bahwa sekarang ini adalah investasi tercepat dan terpendek dari berbagai pendekatan untuk Python 3.5.
Di Python 3.6, biasa dict menjadi terurut dan kompak. (Fitur ini berlaku untuk CPython dan Mount tapi mungkin tidak hadir dalam implementasi lainnya). Yang memberi kita baru cara tercepat deduping sementara tetap mempertahankan urutan:
Di Python 3.7, biasa dict dijamin untuk kedua memerintahkan seluruh implementasi. Jadi, terpendek dan tercepat solusinya adalah:
It's one-liner:
daftar(set(source_list))
akan melakukan trik.Set
adalah sesuatu yang dapat't mungkin memiliki duplikat.Update: sebuah rangka melestarikan pendekatan dua jalur:
Di sini kita menggunakan fakta bahwa
OrderedDict
mengingat penyisipan urutan tombol, dan tidak berubah ketika nilai di kunci tertentu diperbarui. Kita menyisipkanBenar
sebagai nilai-nilai, tetapi kita bisa memasukkan apa-apa, nilai-nilai yang tidak digunakan. (set
bekerja banyak sepertidict
dengan mengabaikan nilai-nilai, juga.)Jika anda don't peduli tentang urutan, lakukan ini:
Set
dijamin untuk tidak memiliki duplikat.Untuk membuat daftar baru tetap mempertahankan urutan pertama unsur-unsur duplikat di
L
newlist=[ii untuk n,ii dalam menghitung(L) jika ii tidak dalam L[:n]]
misalnya
jika L=[1, 2, 2, 3, 4, 2, 4, 3, 5]
kemudiannewlist
akan menjadi[1,2,3,4,5]
Ini cek setiap elemen baru telah muncul sebelumnya dalam daftar sebelum menambahkannya. Juga tidak perlu impor.
Seorang rekan telah mengirim jawaban yang diterima sebagai bagian dari kode nya kepada saya untuk codereview hari ini. Sementara saya pasti mengagumi keanggunan jawaban dalam pertanyaan, saya tidak senang dengan kinerja. Saya telah mencoba solusi ini (saya menggunakan set untuk mengurangi waktu pencarian)
Untuk membandingkan efisiensi, saya menggunakan sampel acak dari 100 bilangan bulat - 62 yang unik
Berikut ini adalah hasil pengukuran
Nah, apa yang terjadi jika diatur dihapus dari solusi?
Hasilnya tidak seburuk dengan OrderedDict, tapi masih lebih dari 3 kali dari solusi asli
Cara lain melakukan:
Ada juga solusi menggunakan Panda dan Numpy. Mereka berdua kembali numpy array sehingga anda harus menggunakan fungsi
.kedaftar()
jika anda ingin daftar.Panda solusi
Menggunakan Panda fungsi
unik()
:Numpy solusi
Menggunakan numpy fungsi
unik()
.Perhatikan bahwa numpy.unik() juga mengurutkan nilai-nilai. Jadi daftar
t2
adalah kembali diurutkan. Jika anda ingin memiliki urutan yang diawetkan menggunakan jawaban ini:Solusi ini tidak begitu elegan dibandingkan dengan yang lain, namun, dibandingkan dengan panda.unik(), numpy.unik() memungkinkan anda juga untuk memeriksa apakah bersarang array yang unik di sepanjang salah satu sumbu dipilih.
Sederhana dan mudah:
Output:
Aku punya dict dalam daftar saya, jadi saya tidak bisa menggunakan pendekatan di atas. Aku punya kesalahan:
Jadi jika anda peduli tentang order dan/atau beberapa item unhashable. Maka anda mungkin menemukan ini berguna:
Beberapa mungkin mempertimbangkan daftar pemahaman dengan efek samping untuk tidak menjadi solusi yang baik. Berikut ini's alternatif:
Semua rangka melestarikan pendekatan I've dilihat di sini sejauh ini baik menggunakan naif perbandingan (dengan O(n^2) waktu-kompleksitas yang terbaik) atau berat-berat
OrderedDicts
/set
+daftar
kombinasi yang terbatas untuk hashable input. Berikut ini adalah hash-independen O(nlogn) solusi:Update ditambahkan
kunci
argumen, dokumentasi dan Python 3 kompatibilitas.Jika anda ingin mempertahankan urutan, dan tidak menggunakan modul-modul eksternal berikut ini adalah cara mudah untuk melakukan hal ini:
``python
Catatan: metode Ini mempertahankan urutan penampilan, jadi, seperti yang terlihat di atas, sembilan akan datang setelah satu karena ini adalah pertama kali muncul. Namun ini adalah hasil yang sama seperti yang anda akan dapatkan dengan melakukan
python dari koleksi import OrderedDict ulist=daftar(OrderedDict.fromkeys(l))
tapi itu jauh lebih pendek, dan berjalan lebih cepat.
Ini bekerja karena setiap kali
fromkeys
fungsi mencoba untuk membuat kunci baru, jika nilai yang sudah ada itu hanya akan menimpa. Ini tidak akan mempengaruhi kamus pada semua namun, sebagaifromkeys
menciptakan kamus mana semua tombol memiliki valueNone
, sehingga secara efektif menghilangkan semua duplikat dengan cara ini.Cobalah menggunakan set:
Anda juga bisa melakukan ini:
Alasan bahwa karya-karya di atas adalah bahwa
index
metode pengembalian hanya indeks pertama dari sebuah elemen. Duplikat unsur-unsur yang lebih tinggi memiliki indeks. Lihat di sini:Mengurangi varian dengan memesan melestarikan:
Asumsikan bahwa kita memiliki daftar:
Mengurangi varian (unefficient):
5 x lebih cepat tapi lebih canggih
Penjelasan:
Anda dapat menggunakan fungsi berikut ini:
Contoh:
Penggunaan:
['ini', 'adalah', 'a', 'daftar', 'dengan', 'dupicates', 'di', 'yang']
Pendekatan terbaik untuk menghapus duplikat dari daftar adalah menggunakan set() fungsi, tersedia dalam python, sekali lagi mengubah yang ditetapkan menjadi daftar
Ada banyak jawaban yang lain menunjukkan cara yang berbeda untuk melakukan hal ini, tetapi mereka're semua operasi batch, dan beberapa dari mereka membuang urutan asli. Yang mungkin baik-baik saja tergantung pada apa yang anda perlu, tetapi jika anda ingin untuk iterate atas nilai-nilai dalam urutan dari contoh pertama dari masing-masing nilai, dan anda ingin menghapus duplikat on-the-fly terhadap semua sekaligus, anda bisa menggunakan generator ini:
Hal ini mengembalikan sebuah generator/iterator, sehingga anda dapat menggunakannya di mana saja bahwa anda dapat menggunakan iterator.
Output:
Jika anda ingin melakukan
daftar
, anda dapat melakukan ini:Output:
Tanpa menggunakan set