İnternette arama yapmayı denedim ama yıkanabilir anlamını bulamadım.
Nesneler olduğunu söylediklerinde hashableveya hashable objectsne anlama geliyor?
İnternette arama yapmayı denedim ama yıkanabilir anlamını bulamadım.
Nesneler olduğunu söylediklerinde hashableveya hashable objectsne anlama geliyor?
Yanıtlar:
Gönderen Python sözlüğü :
Bir nesne, kullanım ömrü boyunca hiçbir zaman değişmeyen bir karma değere sahipse (bir
__hash__()yönteme ihtiyaç duyar ) ve diğer nesnelerle karşılaştırılabilecekse (__eq__()veya bir__cmp__()yönteme ihtiyaç duyarsa) yıkanabilir . Eşit karşılaştırılabilen yıkanabilir nesneler aynı karma değerine sahip olmalıdır.Hashability, bir nesneyi sözlük anahtarı ve küme üyesi olarak kullanılabilir hale getirir, çünkü bu veri yapıları karma değerini dahili olarak kullanır.
Python'un değişmez yerleşik nesnelerinin tümü yıkanabilirken, değiştirilebilir kaplar (listeler veya sözlükler gibi) yoktur. Kullanıcı tanımlı sınıfların örnekleri olan nesneler varsayılan olarak yıkanabilir; hepsi eşitsiz karşılaştırırlar ve karma değerleri onlarındır
id().
hash valueşimdi karma değeri nedir? biraz örnek verebilir misiniz
__hash__(). Daha genel olarak, bkz. En.wikipedia.org/wiki/Hash_function
id(object)16x sonucudur object.__hash__(). Bu nedenle sözlük alıntısı bu sürüm için yanlış - karma değeri değil id(), ancak bundan türetilmiştir (gerçekten de piton 2.7.12 için güncellenmiş dokümanlarda belirtildiği gibi).
hash((1, [2, 3]))Eylem halinde görmeye çalışın . Yıkanabilir terimler sözlüğü girişini düzeltmek için bir istek gönderdim.
Buradaki tüm cevapların python'da yıkanabilir nesnelerin iyi çalışma açıklaması var, ama önce Hashing terimini anlamamız gerektiğine inanıyorum.
Hashing , büyük miktarda verinin hızlı bir şekilde depolanacağı ve erişileceği yüksek performanslı, sahte rasgele erişim veri yapıları oluşturmak için kullanılan bir bilgisayar bilimidir.
Örneğin, 10.000 telefon numaranız varsa ve bunları bir dizide saklamak istiyorsanız (bu, verileri bitişik bellek konumlarında depolayan ve rasgele erişim sağlayan sıralı bir veri yapısıdır), ancak gerekli miktarda bitişik olmayabilir bellek konumları.
Bu nedenle, bunun yerine 100 boyutlu bir dizi kullanabilir ve bir değer kümesini aynı indekslerle eşlemek için bir karma işlevi kullanabilirsiniz ve bu değerler bağlantılı bir listede saklanabilir. Bu, bir diziye benzer bir performans sağlar.
Şimdi, bir karma işlevi, sayıyı dizinin boyutuna bölmek ve geri kalanını dizin olarak almak kadar basit olabilir.
Daha fazla ayrıntı için bkz. Https://en.wikipedia.org/wiki/Hash_function
İşte başka bir iyi referans: http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html
Değişken olmayan her şey (değişebilir olasılıklar, değişmesi muhtemel) hashed edilebilir. Yanında hash fonksiyonunun yanı sıra, eğer bir sınıf varsa, örn. dir(tuple)ve __hash__yöntemi ararken , işte bazı örnekler
#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
Değişmez tiplerin listesi:
int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
Değişken tiplerinin listesi:
list, dict, set, bytearray, user-defined classes
Ellipsisbunun da değişmez bir tip olduğunu ve a için bir anahtar olarak kullanılabileceğini öğrendim dict.
hash(MyClass)
__hash__ve __eq__. Dahası, kullanıcı tanımlı tüm sınıflar bu yöntemleri uygular (ve böylece yıkanabilir), çünkü yöntemleri object(evrensel temel sınıftan) miras alırlar .
Python sözlüğüne göre anladığım kadarıyla, yıkanabilir nesnelerin bir örneğini oluşturduğunuzda, örneğin üyeleri veya değerlerine göre değiştirilemez bir değer de hesaplanır. Örneğin, bu değer aşağıdaki gibi bir dikte içinde bir anahtar olarak kullanılabilir:
>>> 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'
tuple_a ve tuple_c hash değerlerinin aynı üyelere sahip oldukları için aynı olduğunu görebiliriz. Dict_a'daki anahtar olarak tuple_a kullandığımızda, dict_a [tuple_c] değerinin aynı olduğunu bulabiliriz, yani bir diktede anahtar olarak kullanıldıklarında, hash değerleri olduğu için aynı değeri döndürürler. aynısı. Yıkanamayan nesneler için, yöntem karması Yok olarak tanımlanır:
>>> type(dict.__hash__)
<class 'NoneType'>
Bu karma değerin, dinamik bir şekilde değil, örneğin başlatılmasıyla hesaplandığını tahmin ediyorum, bu yüzden sadece değişmez nesneler yıkanabilir. Bu yardımcı olur umarım.
Python'daki yıkanabilir nesneleri anlamak için size çalışan bir örnek vereyim. Bu örnek için 2 Tuples alıyorum. Bir tuple içindeki her değer, ömrü boyunca asla değişmeyen benzersiz bir Hash Değerine sahiptir. Bu yüzden değere dayanarak, iki tuple arasındaki karşılaştırma yapılır. Id () kullanarak bir tuple elemanının hash değerini alabiliriz.


Python'da, nesnenin bir dizin döndürmek için setlerin üyesi olabileceği anlamına gelir. Yani, benzersiz bir kimliği / kimliği var.
örneğin, python 3.3'te:
veri yapısı Listeler yıkanamaz, ancak veri yapısı Tuples yıkanabilir.
idbellekteki nesnenin adresi olan (yaklaşık olarak) ile aynı değildir .
Hashable = hash edilebilir.
Tamam, karma nedir? Karma işlevi, bir nesneyi, örneğin “Python” gibi bir dize alan ve sabit boyutlu bir kod döndüren bir işlevdir. Basit olması için, dönüş değerinin bir tam sayı olduğunu varsayalım.
Python 3'te karma ('Python') çalıştırdığımda sonuç olarak 5952713340227947791 alıyorum. Python'un farklı sürümleri temeldeki hash işlevini değiştirmekte özgürdür, bu nedenle muhtemelen farklı bir değer elde edersiniz. Önemli olan şu ki, artık birçok kez karma ('Python') çalıştırsam, her zaman aynı sonucu Python ile alacağım.
Ancak hash ('Java') 1753925553814008565 değerini döndürür. Dolayısıyla, karma yaptığım nesne değişirse, sonuç da değişir. Öte yandan, hash ettiğim nesne değişmezse, sonuç aynı kalır.
Bu neden önemli?
Örneğin, Python sözlükleri anahtarların değişmez olmasını gerektirir. Yani, anahtarlar değişmeyen nesneler olmalıdır. Dizeler, diğer temel tipler (int, float, bool) gibi Python'da değişmezdir. Tuples ve frozensets de değişmezdir. Öte yandan listeler değiştirilemez (yani değiştirilebilir), çünkü bunları değiştirebilirsiniz. Benzer şekilde, dikmeler değiştirilebilir.
Yani bir şeyin yıkanabilir olduğunu söylediğimizde, değişmez olduğunu kastediyoruz. Hash () işlevine değiştirilebilir bir tür iletmeye çalışırsam başarısız olur:
>>> 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
Python'da, herhangi bir değişmez nesne (bir tamsayı, boole, dize, tuple gibi) yıkanabilir, yani ömrü boyunca değeri değişmez. Bu, Python'un sözlükler tarafından benzersiz anahtarları izlemek için kullanılabileceği ve benzersiz değerleri izlemek için kümeler kullanabileceği benzersiz bir hash değeri oluşturmasına izin verir.
Bu yüzden Python sözlükteki anahtarlar için değiştirilemez veri tipleri kullanmamızı gerektirir.
Bir karma tabloyu sıfırdan oluşturmak için, tüm değerlerin "Yok" olarak ayarlanması ve bir gereksinim ortaya çıktığında değiştirilmesi gerekir. Yıkanabilir nesneler değiştirilebilir veri tiplerini (Sözlük, listeler vb.) İfade eder. Öte yandan setler atandıktan sonra yeniden başlatılamaz, bu nedenle setler yıkanamaz. Oysa set () - frozenset () - varyantı yıkanabilir.
__hash__()yönteme bakınız .