Saya memiliki sekitar 10 juta nilai yang harus saya masukkan ke dalam beberapa jenis tabel pencarian, jadi saya bertanya-tanya mana yang akan lebih efisien daftar atau dikt ?
Saya tahu Anda dapat melakukan sesuatu seperti ini untuk keduanya:
if something in dict_of_stuff:
pass
dan
if something in list_of_stuff:
pass
Pikiran saya adalah dikt akan lebih cepat dan lebih efisien.
Terima kasih atas bantuan Anda.
Sunting 1
Sedikit info lagi tentang apa yang saya coba lakukan. Masalah Euler 92 . Saya sedang membuat tabel pencarian untuk melihat apakah nilai yang dihitung sudah siap dihitung.
EDIT 2
Efisiensi untuk mencari.
EDIT 3
Tidak ada nilai yang diasosiasikan dengan nilai ... jadi apakah himpunan akan lebih baik?
python
performance
Nggak
sumber
sumber
Jawaban:
Mempercepat
Pencarian dalam daftar adalah O (n), pencarian dalam kamus diamortisasi O (1), berkenaan dengan jumlah item dalam struktur data. Jika Anda tidak perlu mengaitkan nilai, gunakan set.
Penyimpanan
Baik kamus dan set menggunakan hashing dan mereka menggunakan lebih banyak memori daripada hanya untuk penyimpanan objek. Menurut AM Kuchling dalam Kode Indah , implementasi mencoba untuk menjaga hash 2/3 penuh, sehingga Anda mungkin membuang cukup banyak memori.
Jika Anda tidak menambahkan entri baru dengan cepat (yang Anda lakukan, berdasarkan pertanyaan Anda yang diperbarui), mungkin ada baiknya menyortir daftar dan menggunakan pencarian biner. Ini adalah O (log n), dan cenderung lebih lambat untuk string, tidak mungkin untuk objek yang tidak memiliki urutan alami.
sumber
Dict adalah tabel hash, jadi sangat cepat untuk menemukan kunci. Jadi antara dict dan daftar, dict akan lebih cepat. Tetapi jika Anda tidak memiliki nilai untuk dikaitkan, lebih baik menggunakan satu set. Ini adalah tabel hash, tanpa bagian "table".
EDIT: untuk pertanyaan baru Anda, YA, satu set akan lebih baik. Cukup buat 2 set, satu untuk urutan berakhir dengan 1 dan lainnya untuk urutan berakhir pada 89. Saya telah berhasil memecahkan masalah ini menggunakan set.
sumber
set()
persis apa yang Anda inginkan. O (1) pencarian, dan lebih kecil dari dict.sumber
Saya melakukan benchmarking dan ternyata dict lebih cepat daripada daftar dan ditetapkan untuk set data besar, menjalankan python 2.7.3 pada CPU i7 di linux:
python -mtimeit -s 'd=range(10**7)' '5*10**6 in d'
10 loop, terbaik 3: 64,2 msec per loop
python -mtimeit -s 'd=dict.fromkeys(range(10**7))' '5*10**6 in d'
10000000 loop, terbaik 3: 0,0759 usec per loop
python -mtimeit -s 'from sets import Set; d=Set(range(10**7))' '5*10**6 in d'
10.00000 loop, terbaik 3: 0,262 usec per loop
Seperti yang Anda lihat, dict jauh lebih cepat dari daftar dan sekitar 3 kali lebih cepat dari yang ditetapkan. Dalam beberapa aplikasi Anda mungkin masih ingin memilih set untuk keindahannya. Dan jika set data benar-benar kecil (<1000 elemen) daftar berkinerja cukup baik.
sumber
-s
opsinya adalah mengaturtimeit
lingkungan, yaitu tidak dihitung dalam total waktu. The-s
opsi dijalankan hanya sekali. Pada Python 3.3, saya mendapatkan hasil ini: gen (range) -> 0,229 usec, daftar -> 157 msec, dict -> 0,0806 usec, set -> 0,0807 usec. Mengatur dan mendiktekan kinerja adalah sama. Namun Dict membutuhkan waktu lebih lama untuk diinisialisasi daripada yang ditetapkan (total waktu 13,580s v. 11,803s)python -mtimeit -s "d=set(range(10**7))" "5*10**6 in d"
menggunakan Python 3.6.0 (10.000000 loop, terbaik 3: 0,0608 usec per loop), kira-kira sama dengan benchmark dict jadi terima kasih atas komentar Anda.Anda menginginkan sebuah dikt.
Untuk daftar (tidak disortir) dalam Python, operasi "dalam" memerlukan waktu O (n) --- tidak baik ketika Anda memiliki sejumlah besar data. Dict, di sisi lain, adalah tabel hash, sehingga Anda dapat mengharapkan O (1) waktu pencarian.
Seperti yang telah dicatat orang lain, Anda mungkin memilih satu set (jenis dict khusus) sebagai gantinya, jika Anda hanya memiliki kunci daripada pasangan kunci / nilai.
Terkait:
sumber
in
operator yang diterapkan ke daftar yang disortir berkinerja lebih baik daripada ketika diterapkan pada yang tidak disortir (untuk pencarian nilai acak)? (Saya tidak berpikir apakah mereka diimplementasikan secara internal sebagai vektor atau sebagai node dalam daftar tertaut adalah relevan.)jika data adalah set unik () akan menjadi yang paling efisien, tetapi dari dua - dict (yang juga membutuhkan keunikan, oops :)
sumber
Sebagai rangkaian tes baru untuk menunjukkan @ EriF89 masih tepat setelah bertahun-tahun:
Di sini kami juga membandingkan a
tuple
, yang diketahui lebih cepat daripadalists
(dan menggunakan lebih sedikit memori) dalam beberapa kasus penggunaan. Dalam hal tabel pencarian,tuple
faired tidak lebih baik.Baik itu
dict
danset
dilakukan dengan sangat baik. Ini memunculkan poin menarik yang mengaitkan jawaban @ SilentGhost tentang keunikan: jika OP memiliki nilai 10M dalam kumpulan data, dan tidak diketahui jika ada duplikat di dalamnya, maka ada baiknya menjaga set / dikt elemen-elemennya secara paralel. dengan set data aktual, dan pengujian untuk keberadaan dalam set / dikt itu. Mungkin saja 10M titik data hanya memiliki 10 nilai unik, yang merupakan ruang yang jauh lebih kecil untuk mencari!Kesalahan SilentGhost tentang dicts sebenarnya menerangi karena seseorang dapat menggunakan dict untuk mengkorelasikan data duplikat (dalam nilai) ke dalam set (kunci) yang tidak ter-duplikasi, dan dengan demikian menyimpan satu objek data untuk menyimpan semua data, namun masih secepat tabel pencarian. Misalnya, kunci dict dapat berupa nilai yang dicari, dan nilai tersebut dapat berupa daftar indeks dalam daftar imajiner tempat nilai tersebut terjadi.
Misalnya, jika daftar data sumber yang akan dicari adalah
l=[1,2,3,1,2,1,4]
, itu bisa dioptimalkan untuk pencarian dan memori dengan menggantinya dengan dict ini:Dengan dikt ini, orang bisa tahu:
2 in d
pengembalianTrue
)d[2]
mengembalikan daftar indeks dimana data ditemukan dalam daftar data asli:[1, 4]
)sumber
Anda sebenarnya tidak perlu menyimpan 10 juta nilai dalam tabel, jadi itu bukan masalah besar.
Petunjuk: pikirkan seberapa besar hasil Anda setelah operasi jumlah kotak pertama. Hasil terbesar yang mungkin akan jauh lebih kecil dari 10 juta ...
sumber