Saya perlu memverifikasi apakah daftar adalah subset dari yang lain - pengembalian boolean yang saya cari.
Apakah menguji kesetaraan pada daftar yang lebih kecil setelah persimpangan merupakan cara tercepat untuk melakukan ini? Kinerja sangat penting mengingat jumlah dataset yang perlu dibandingkan.
Menambahkan fakta lebih lanjut berdasarkan diskusi:
Apakah salah satu daftar akan sama untuk banyak tes? Itu karena salah satu dari mereka adalah tabel pencarian statis.
Apakah itu perlu daftar? Tidak - tabel pencarian statis dapat berupa apa saja yang berkinerja terbaik. Yang dinamis adalah dict dari mana kita mengekstrak kunci untuk melakukan pencarian statis.
Apa solusi optimal yang diberikan skenario?
Jawaban:
Fungsi performansi yang disediakan oleh Python untuk ini adalah
set.issubset
. Namun ada beberapa batasan yang membuatnya tidak jelas apakah itu jawaban untuk pertanyaan Anda.Daftar dapat berisi item beberapa kali dan memiliki urutan tertentu. Satu set tidak. Selain itu, set hanya berfungsi pada objek hashable .
Apakah Anda bertanya tentang subset atau urutan (yang berarti Anda ingin algoritma pencarian string)? Apakah salah satu daftar akan sama untuk banyak tes? Apa tipe data yang ada dalam daftar? Dan untuk itu, apakah perlu daftar?
Posting Anda yang lain memotong dict dan daftar membuat jenis lebih jelas dan memang mendapat rekomendasi untuk menggunakan tampilan kunci kamus untuk fungsionalitas seperti set mereka. Dalam kasus itu diketahui berfungsi karena kunci kamus berperilaku seperti satu set (sangat banyak sehingga sebelum kita memiliki set di Python kami menggunakan kamus). Orang bertanya-tanya bagaimana masalah menjadi kurang spesifik dalam tiga jam.
sumber
sumber
set(a).issubset(b)
karena dalam hal ini Anda hanya mengkonversia
ke set tetapi tidakb
, yang menghemat waktu. Anda dapat menggunakantimeit
untuk membandingkan waktu yang digunakan dalam dua perintah. Misalnya,timeit.repeat('set(a)<set(b)', 'a = [1,3,5]; b = [1,3,5,7]', number=1000)
dantimeit.repeat('set(a).issubset(b)', 'a = [1,3,5]; b = [1,3,5,7]', number=1000)
issubset
dilakukan adalah memeriksa apakah argumennya adalahset
/frozenset
, dan jika tidak, ia mengubahnya menjadi sementaraset
untuk perbandingan, menjalankan cek, lalu membuang sementaraset
. Perbedaan waktu (jika ada) akan menjadi faktor perbedaan kecil dalam biaya pencarian LEGB (menemukanset
yang kedua kali lebih mahal daripada pencarian atribut pada yang sudah adaset
), tetapi sebagian besar merupakan pencucian untuk input yang cukup besar.Penjelasan: Generator membuat booleans dengan mengulang daftar
one
memeriksa apakah item itu ada dalam daftartwo
.all()
kembaliTrue
jika setiap item benar, selain ituFalse
.Ada juga keuntungan yang
all
mengembalikan False pada elemen pertama elemen yang hilang daripada harus memproses setiap item.sumber
set(one).issubset(set(two))
adalah solusi yang bagus. Dengan solusi yang saya posting Anda harus dapat menggunakannya dengan objek apa pun jika mereka memiliki operator pembanding yang tepat.all
hubungan pendek dengan benar, yang terakhir akan melakukan semua pemeriksaan bahkan jika akan jelas dari pemeriksaan pertama bahwa tes akan gagal. Jatuhkan kurung kotak untuk mendapatkanall(x in two for x in one)
.Dengan asumsi barang-barang itu bisa dipecahkan
Jika Anda tidak peduli dengan item duplikat misalnya.
[1, 2, 2]
dan[1, 2]
kemudian hanya menggunakan:.issubset
akan menjadi cara tercepat untuk melakukannya. Memeriksa panjang sebelum pengujianissubset
tidak akan meningkatkan kecepatan karena Anda masih memiliki item O (N + M) untuk diulangi dan diperiksa.sumber
Satu lagi solusi adalah menggunakan a
intersection
.Perpotongan set akan berisi
set one
(ATAU)
sumber
Jika list1 ada dalam daftar 2:
(x in two for x in one)
menghasilkan daftarTrue
.ketika kita melakukan
set(x in two for x in one)
hanya memiliki satu elemen (Benar).sumber
Teori himpunan tidak sesuai untuk daftar karena duplikat akan menghasilkan jawaban yang salah menggunakan teori himpunan.
Sebagai contoh:
tidak ada artinya. Ya, itu memberikan jawaban yang salah tetapi ini tidak benar karena teori himpunan hanya membandingkan: 1,3,5 vs 1,3,4,5. Anda harus memasukkan semua duplikat.
Alih-alih, Anda harus menghitung setiap kemunculan setiap item dan melakukan yang lebih besar dari yang sama untuk memeriksanya. Ini tidak terlalu mahal, karena tidak menggunakan operasi O (N ^ 2) dan tidak memerlukan penyortiran cepat.
Kemudian menjalankan ini Anda dapatkan:
sumber
Karena tidak ada yang mempertimbangkan membandingkan dua string, inilah proposal saya.
Anda tentu saja ingin memeriksa apakah pipa ("|") bukan bagian dari salah satu daftar dan mungkin memilih secara otomatis char lain, tetapi Anda mendapatkan idenya.
Menggunakan string kosong sebagai pemisah bukanlah solusi karena angka dapat memiliki beberapa digit ([12,3]! = [1,23])
sumber
Maafkan saya jika saya terlambat ke pesta. ;)
Untuk memeriksa apakah
set A
ada subset dariset B
,Python
memilikiA.issubset(B)
danA <= B
. Iniset
hanya berfungsi dan berfungsi dengan baik, tetapi kerumitan implementasi internal tidak diketahui. Referensi: https://docs.python.org/2/library/sets.html#set-objectsSaya datang dengan sebuah algoritma untuk memeriksa apakah
list A
ada himpunan bagianlist B
dengan komentar berikut.sort
kedua daftar terlebih dahulu sebelum membandingkan elemen untuk memenuhi syarat untuk subset.break
yangloop
ketika nilai elemen daftar keduaB[j]
lebih besar dari nilai elemen daftar pertamaA[i]
.last_index_j
digunakan untuk memulailoop
darilist B
mana terakhir kali ditinggalkan. Ini membantu menghindari memulai perbandingan dari awallist B
(yang, seperti yang Anda duga tidak perlu, untuk memulailist B
dari yangindex 0
berikutnyaiterations
.)Kompleksitas akan menjadi
O(n ln n)
masing-masing untuk mengurutkan kedua daftar danO(n)
untuk memeriksa subset.O(n ln n) + O(n ln n) + O(n) = O(n ln n)
.Kode memiliki banyak
print
pernyataan untuk melihat apa yang terjadi di masingiteration
- masingloop
. Ini dimaksudkan hanya untuk pengertian.Periksa apakah satu daftar adalah himpunan bagian dari daftar lain
Keluaran
sumber
Kode di bawah ini memeriksa apakah suatu himpunan merupakan "himpunan bagian yang tepat" dari himpunan lain
sumber
Dalam python 3.5 Anda bisa melakukan
[*set()][index]
untuk mendapatkan elemen. Ini adalah solusi yang jauh lebih lambat daripada metode lain.atau hanya dengan len dan set
sumber
Berikut adalah bagaimana saya tahu jika satu daftar adalah bagian dari yang lain, urutannya penting bagi saya dalam kasus saya.
sumber
Sebagian besar solusi menganggap bahwa daftar tidak memiliki duplikat. Jika daftar Anda memiliki duplikat, Anda dapat mencoba ini:
Ini memastikan bahwa sublist tidak pernah memiliki elemen yang berbeda dari daftar atau elemen umum dalam jumlah yang lebih besar.
sumber
Jika Anda bertanya apakah satu daftar "terkandung" di daftar lain, maka:
Jika Anda bertanya apakah setiap elemen dalam listA memiliki jumlah elemen pencocokan yang sama di listB coba:
sumber
Jika
a2 is subset of a1
demikianLength of set(a1 + a2) == Length of set(a1)
sumber