Objek hashable jika memiliki nilai hash yang tidak pernah berubah selama masa hidupnya (ia membutuhkan __hash__()metode), dan dapat dibandingkan dengan objek lain (itu membutuhkan metode __eq__()atau __cmp__()). Objek yang dapat di-hasashkan yang membandingkannya sama harus memiliki nilai hash yang sama.
Hashability membuat objek dapat digunakan sebagai kunci kamus dan anggota yang ditetapkan, karena struktur data ini menggunakan nilai hash secara internal.
Semua objek bawaan Python yang tidak dapat diubah adalah hashable, sementara tidak ada wadah yang bisa berubah (seperti daftar atau kamus). Objek yang merupakan instance dari kelas yang ditentukan pengguna secara default dapat hashable; mereka semua membandingkan tidak setara, dan nilai hash mereka adalah milik mereka id().
@ TorstenBronger: Karena dua objek yang tidak sama dapat hash ke nilai yang sama. Dengan kata lain, hashing adalah lossy.
NPE
1
Dalam python-2.7.12, hasil id(object)adalah 16x hasil object.__hash__(). Jadi kutipan glosarium tidak benar untuk versi ini - nilai hash tidak id(), tetapi berasal dari itu (seperti yang memang dicatat dalam dokumen yang diperbarui untuk python 2.7.12).
davidA
2
Saya tahu ini adalah posting lama, tetapi perlu disebutkan bahwa entri glosari yang disalin di sini tidak sepenuhnya benar. Anda bisa meletakkan objek yang bisa berubah-ubah (seperti daftar) di dalam tuple. Tuple masih tidak berubah, tetapi Anda dapat mengubah daftar di dalamnya, jadi itu tidak bisa diacak. Cobalah hash((1, [2, 3]))melihatnya dalam aksi. Saya telah mengirim permintaan untuk memperbaiki entri glosari untuk hashable.
John Riehl
102
Semua jawaban di sini memiliki penjelasan kerja yang baik dari objek hashable di python, tapi saya percaya orang perlu memahami istilah Hashing terlebih dahulu.
Hashing adalah konsep dalam ilmu komputer yang digunakan untuk membuat struktur data akses acak pseudo kinerja tinggi di mana sejumlah besar data harus disimpan dan diakses dengan cepat.
Misalnya, jika Anda memiliki 10.000 nomor telepon, dan Anda ingin menyimpannya dalam sebuah array (yang merupakan struktur data sekuensial yang menyimpan data di lokasi memori yang berdekatan, dan menyediakan akses acak), tetapi Anda mungkin tidak memiliki jumlah yang diperlukan secara bersamaan lokasi memori.
Jadi, Anda bisa menggunakan array ukuran 100, dan menggunakan fungsi hash untuk memetakan serangkaian nilai ke indeks yang sama, dan nilai-nilai ini dapat disimpan dalam daftar tertaut. Ini memberikan kinerja yang mirip dengan array.
Sekarang, fungsi hash dapat sesederhana membagi angka dengan ukuran array dan mengambil sisanya sebagai indeks.
Itu perspektif yang menarik tentang hashing. Saya belum memikirkannya dengan cara itu.
yuvgin
@yuvgin hash-tables sering digunakan untuk mengimplementasikan jarang-array (yaitu contoh yang diberikan di sini).
Eli Korvigo
@EliKorvigo Saya suka menganggap array reguler sebagai versi hash table yang sangat dioptimalkan.
Mark Ransom
1
dapatkah Anda membuat beberapa kode sederhana mengenai skenario susunan nomor telepon untuk memperjelas konsep hashing?
Istiaque Ahmed
18
Apa pun yang tidak bisa berubah (artinya bisa berubah, cenderung berubah) dapat di-hash. Selain fungsi hash yang harus dicari, jika suatu kelas memilikinya, misalnya. dir(tuple)dan mencari __hash__metodenya, berikut adalah beberapa contohnya
#x = hash(set([1,2])) #set unhashable
x = hash(frozenset([1,2]))#hashable#x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable
x = hash((1,2,3))#tuple of immutable objects, hashable#x = hash()#x = hash({1,2}) #list of mutable objects, unhashable#x = hash([1,2,3]) #list of immutable objects, unhashable
Baru-baru ini saya menemukan bahwa Ellipsisini juga merupakan tipe yang tidak dapat diubah dan dapat digunakan sebagai kunci untuk dict.
Gábor Fekete
Bahkan kelas yang ditentukan pengguna dapat digunakan tetapi hanya nama mereka bukan turunan. Contoh:hash(MyClass)
Gábor Fekete
1
@ GáborFekete instance dari kelas yang ditentukan pengguna dapat di hash jika kelas mereka menerapkan __hash__dan __eq__. Selain itu, semua kelas yang ditentukan pengguna menerapkan metode ini (dan dengan demikian dapat hashable), karena mereka mewarisi metode dari object(kelas dasar universal).
Eli Korvigo
7
Dalam pemahaman saya menurut glosarium Python, ketika Anda membuat instance objek yang hashable, nilai yang tidak dapat diubah juga dihitung menurut anggota atau nilai instance. Misalnya, nilai itu kemudian dapat digunakan sebagai kunci dalam dict seperti di bawah ini:
>>> tuple_a =(1,2,3)>>> tuple_a.__hash__()2528502973977326415>>> tuple_b =(2,3,4)>>> tuple_b.__hash__()3789705017596477050>>> tuple_c =(1,2,3)>>> tuple_c.__hash__()2528502973977326415>>> id(a)== id(c)# a and c same object?False>>> a.__hash__()== c.__hash__()# a and c same value?True>>> dict_a ={}>>> dict_a[tuple_a]='hiahia'>>> dict_a[tuple_c]'hiahia'
kita dapat menemukan bahwa nilai hash dari tuple_a dan tuple_c adalah sama karena mereka memiliki anggota yang sama. Ketika kita menggunakan tuple_a sebagai kunci di dict_a, kita dapat menemukan bahwa nilai untuk dict_a [tuple_c] adalah sama, yang berarti bahwa, ketika mereka digunakan sebagai kunci dalam dict, mereka mengembalikan nilai yang sama karena nilai hash adalah sama. Untuk objek-objek yang tidak hashable, metode hash didefinisikan sebagai None:
>>> type(dict.__hash__)<class'NoneType'>
Saya kira nilai hash ini dihitung berdasarkan inisialisasi instance, tidak secara dinamis, itu sebabnya hanya objek yang tidak dapat diubah yang hashable. Semoga ini membantu.
Biarkan saya memberi Anda contoh untuk memahami objek hashable di python. Saya mengambil 2 Tuples untuk contoh ini. Setiap nilai dalam tupel memiliki Nilai Hash yang unik yang tidak pernah berubah selama masa pakainya. Jadi berdasarkan ini memiliki nilai, perbandingan antara dua tupel dilakukan. Kita bisa mendapatkan nilai hash dari elemen tuple menggunakan ID ().
ini akan lebih bermanfaat sebagai teks daripada gambar
baxx
7
itu jawaban yang salah. id () menunjukkan alamat yang direferensikan dalam memori, itu bukan nilai hash. Untuk mendapatkan hash gunakan fungsi __hash __ (). misalnya: t1 .__ hash __ ()
Vlad
@ascentman Jangan ragu untuk mengedit jawaban yang Anda yakini salah. Hasil edit Anda akan ditinjau oleh rekan sejawat dan, jika diterima, Anda mendapat hadiah skor kecil untuk itu.
XavierStuvw
4
Dalam python itu berarti bahwa objek dapat menjadi anggota set untuk mengembalikan indeks. Artinya, mereka memiliki identitas / id unik.
misalnya, dalam python 3.3:
struktur data Daftar bukan hashable tetapi struktur data Tuples hashable.
Hash tidak sama dengan id, yaitu (kurang-lebih) alamat objek di memori.
poolie
3
Hashable = mampu di-hash.
Ok, apa hashing itu? Fungsi hashing adalah fungsi yang mengambil objek, katakan string seperti "Python," dan mengembalikan kode ukuran tetap. Untuk kesederhanaan, anggap nilai pengembalian adalah bilangan bulat
Ketika saya menjalankan hash ('Python') di Python 3, saya mendapatkan 5952713340227947791 sebagai hasilnya. Versi berbeda dari Python bebas untuk mengubah fungsi hash yang mendasarinya, sehingga Anda kemungkinan akan mendapatkan nilai yang berbeda. Yang penting adalah bahwa tidak masalah sekarang berkali-kali saya menjalankan hash ('Python'), saya akan selalu mendapatkan hasil yang sama dengan versi Python yang sama.
Tapi hash ('Java') mengembalikan 1753925553814008565. Jadi, jika objek saya hashing berubah, demikian juga hasilnya. Di sisi lain, jika objek yang saya hashing tidak berubah, maka hasilnya tetap sama.
Mengapa ini penting?
Nah, kamus Python, misalnya, membutuhkan kunci agar tidak berubah. Artinya, kunci harus berupa benda yang tidak berubah. String tidak dapat diubah dalam Python, seperti halnya tipe dasar lainnya (int, float, bool). Tuple dan frozenset juga tidak berubah. Daftar, di sisi lain, tidak berubah (yaitu, mereka bisa berubah) karena Anda dapat mengubahnya. Demikian pula, dikte bisa berubah.
Jadi ketika kita mengatakan sesuatu itu hashable, maksud kita itu tidak berubah. Jika saya mencoba meneruskan tipe yang bisa diubah ke fungsi hash (), itu akan gagal:
>>> hash('Python')1687380313081734297>>> hash('Java')1753925553814008565>>>>>> hash([1,2])Traceback(most recent call last):File"<stdin>", line 1,in<module>TypeError: unhashable type:'list'>>> hash({1,2})Traceback(most recent call last):File"<stdin>", line 1,in<module>TypeError: unhashable type:'set'>>> hash({1:2})Traceback(most recent call last):File"<stdin>", line 1,in<module>TypeError: unhashable type:'dict'>>>>>> hash(frozenset({1,2}))-1834016341293975159>>> hash((1,2))3713081631934410656
Perhatikan bahwa python secara acak biji algoritma hashing pada awal setiap proses. Oleh karena itu, Anda benar-benar akan mendapatkan nilai hash yang berbeda jika Anda menjalankan hash ('Python') dua kali dalam proses yang berbeda.
D Hudson
2
Dalam Python, objek yang tidak dapat diubah (seperti integer, boolean, string, tuple) adalah hashable, artinya nilainya tidak berubah selama masa pakainya. Ini memungkinkan Python untuk membuat nilai hash unik untuk mengidentifikasinya, yang dapat digunakan oleh kamus untuk melacak kunci dan set unik untuk melacak nilai-nilai unik.
Inilah sebabnya mengapa Python mengharuskan kita untuk menggunakan tipe data yang tidak dapat diubah untuk kunci-kunci dalam kamus.
Untuk membuat tabel hashing dari awal, semua nilai harus diatur ke "Tidak Ada" dan dimodifikasi begitu persyaratan muncul. Objek yang dapat hash mengacu pada tipe data yang dapat dimodifikasi (Kamus, daftar, dll). Set di sisi lain tidak dapat diinisialisasi ulang setelah ditugaskan, sehingga set tidak dapat hashable. Padahal, Varian dari set () - frozenset () - adalah hashable.
__hash__()
metodenya .Jawaban:
Dari daftar istilah Python :
sumber
hash value
sekarang apa itu nilai hash. dapatkah Anda memberikan beberapa contoh__hash__()
. Secara umum, lihat en.wikipedia.org/wiki/Hash_functionid(object)
adalah 16x hasilobject.__hash__()
. Jadi kutipan glosarium tidak benar untuk versi ini - nilai hash tidakid()
, tetapi berasal dari itu (seperti yang memang dicatat dalam dokumen yang diperbarui untuk python 2.7.12).hash((1, [2, 3]))
melihatnya dalam aksi. Saya telah mengirim permintaan untuk memperbaiki entri glosari untuk hashable.Semua jawaban di sini memiliki penjelasan kerja yang baik dari objek hashable di python, tapi saya percaya orang perlu memahami istilah Hashing terlebih dahulu.
Hashing adalah konsep dalam ilmu komputer yang digunakan untuk membuat struktur data akses acak pseudo kinerja tinggi di mana sejumlah besar data harus disimpan dan diakses dengan cepat.
Misalnya, jika Anda memiliki 10.000 nomor telepon, dan Anda ingin menyimpannya dalam sebuah array (yang merupakan struktur data sekuensial yang menyimpan data di lokasi memori yang berdekatan, dan menyediakan akses acak), tetapi Anda mungkin tidak memiliki jumlah yang diperlukan secara bersamaan lokasi memori.
Jadi, Anda bisa menggunakan array ukuran 100, dan menggunakan fungsi hash untuk memetakan serangkaian nilai ke indeks yang sama, dan nilai-nilai ini dapat disimpan dalam daftar tertaut. Ini memberikan kinerja yang mirip dengan array.
Sekarang, fungsi hash dapat sesederhana membagi angka dengan ukuran array dan mengambil sisanya sebagai indeks.
Untuk detail lebih lanjut, lihat https://en.wikipedia.org/wiki/Hash_function
Berikut ini adalah referensi bagus lainnya: http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html
sumber
Apa pun yang tidak bisa berubah (artinya bisa berubah, cenderung berubah) dapat di-hash. Selain fungsi hash yang harus dicari, jika suatu kelas memilikinya, misalnya.
dir(tuple)
dan mencari__hash__
metodenya, berikut adalah beberapa contohnyaDaftar jenis yang tidak berubah:
Daftar jenis yang bisa berubah:
sumber
Ellipsis
ini juga merupakan tipe yang tidak dapat diubah dan dapat digunakan sebagai kunci untukdict
.hash(MyClass)
__hash__
dan__eq__
. Selain itu, semua kelas yang ditentukan pengguna menerapkan metode ini (dan dengan demikian dapat hashable), karena mereka mewarisi metode dariobject
(kelas dasar universal).Dalam pemahaman saya menurut glosarium Python, ketika Anda membuat instance objek yang hashable, nilai yang tidak dapat diubah juga dihitung menurut anggota atau nilai instance. Misalnya, nilai itu kemudian dapat digunakan sebagai kunci dalam dict seperti di bawah ini:
kita dapat menemukan bahwa nilai hash dari tuple_a dan tuple_c adalah sama karena mereka memiliki anggota yang sama. Ketika kita menggunakan tuple_a sebagai kunci di dict_a, kita dapat menemukan bahwa nilai untuk dict_a [tuple_c] adalah sama, yang berarti bahwa, ketika mereka digunakan sebagai kunci dalam dict, mereka mengembalikan nilai yang sama karena nilai hash adalah sama. Untuk objek-objek yang tidak hashable, metode hash didefinisikan sebagai None:
Saya kira nilai hash ini dihitung berdasarkan inisialisasi instance, tidak secara dinamis, itu sebabnya hanya objek yang tidak dapat diubah yang hashable. Semoga ini membantu.
sumber
Biarkan saya memberi Anda contoh untuk memahami objek hashable di python. Saya mengambil 2 Tuples untuk contoh ini. Setiap nilai dalam tupel memiliki Nilai Hash yang unik yang tidak pernah berubah selama masa pakainya. Jadi berdasarkan ini memiliki nilai, perbandingan antara dua tupel dilakukan. Kita bisa mendapatkan nilai hash dari elemen tuple menggunakan ID ().
sumber
Dalam python itu berarti bahwa objek dapat menjadi anggota set untuk mengembalikan indeks. Artinya, mereka memiliki identitas / id unik.
misalnya, dalam python 3.3:
struktur data Daftar bukan hashable tetapi struktur data Tuples hashable.
sumber
id
, yaitu (kurang-lebih) alamat objek di memori.Hashable = mampu di-hash.
Ok, apa hashing itu? Fungsi hashing adalah fungsi yang mengambil objek, katakan string seperti "Python," dan mengembalikan kode ukuran tetap. Untuk kesederhanaan, anggap nilai pengembalian adalah bilangan bulat
Ketika saya menjalankan hash ('Python') di Python 3, saya mendapatkan 5952713340227947791 sebagai hasilnya. Versi berbeda dari Python bebas untuk mengubah fungsi hash yang mendasarinya, sehingga Anda kemungkinan akan mendapatkan nilai yang berbeda. Yang penting adalah bahwa tidak masalah sekarang berkali-kali saya menjalankan hash ('Python'), saya akan selalu mendapatkan hasil yang sama dengan versi Python yang sama.
Tapi hash ('Java') mengembalikan 1753925553814008565. Jadi, jika objek saya hashing berubah, demikian juga hasilnya. Di sisi lain, jika objek yang saya hashing tidak berubah, maka hasilnya tetap sama.
Mengapa ini penting?
Nah, kamus Python, misalnya, membutuhkan kunci agar tidak berubah. Artinya, kunci harus berupa benda yang tidak berubah. String tidak dapat diubah dalam Python, seperti halnya tipe dasar lainnya (int, float, bool). Tuple dan frozenset juga tidak berubah. Daftar, di sisi lain, tidak berubah (yaitu, mereka bisa berubah) karena Anda dapat mengubahnya. Demikian pula, dikte bisa berubah.
Jadi ketika kita mengatakan sesuatu itu hashable, maksud kita itu tidak berubah. Jika saya mencoba meneruskan tipe yang bisa diubah ke fungsi hash (), itu akan gagal:
sumber
Dalam Python, objek yang tidak dapat diubah (seperti integer, boolean, string, tuple) adalah hashable, artinya nilainya tidak berubah selama masa pakainya. Ini memungkinkan Python untuk membuat nilai hash unik untuk mengidentifikasinya, yang dapat digunakan oleh kamus untuk melacak kunci dan set unik untuk melacak nilai-nilai unik.
Inilah sebabnya mengapa Python mengharuskan kita untuk menggunakan tipe data yang tidak dapat diubah untuk kunci-kunci dalam kamus.
sumber
Untuk membuat tabel hashing dari awal, semua nilai harus diatur ke "Tidak Ada" dan dimodifikasi begitu persyaratan muncul. Objek yang dapat hash mengacu pada tipe data yang dapat dimodifikasi (Kamus, daftar, dll). Set di sisi lain tidak dapat diinisialisasi ulang setelah ditugaskan, sehingga set tidak dapat hashable. Padahal, Varian dari set () - frozenset () - adalah hashable.
sumber