Próbowałem przeszukać internet, ale nie mogłem znaleźć znaczenia skrótu.
Kiedy mówią, że przedmioty są hashable
lub hashable objects
co to oznacza?
Próbowałem przeszukać internet, ale nie mogłem znaleźć znaczenia skrótu.
Kiedy mówią, że przedmioty są hashable
lub hashable objects
co to oznacza?
Odpowiedzi:
Ze słownika Python :
Obiekt jest haszowalny, jeśli ma wartość skrótu, która nigdy się nie zmienia w trakcie jego życia (potrzebuje
__hash__()
metody), i można go porównać do innych obiektów (potrzebuje metody__eq__()
lub__cmp__()
). Obiekty haszujące, które porównują równe, muszą mieć tę samą wartość skrótu.Hashability sprawia, że obiekt nadaje się do użycia jako klucz słownika i element członkowski, ponieważ te struktury danych wewnętrznie używają wartości skrótu.
Wszystkie niezmienne wbudowane obiekty Pythona są haszowalne, podczas gdy żadne zmienne kontenery (takie jak listy lub słowniki) nie są. Obiekty będące instancjami klas zdefiniowanych przez użytkownika są domyślnie mieszalne; wszystkie porównują nierówne, a ich wartość skrótu jest ich
id()
.
hash value
teraz wartość hash. czy możesz podać jakiś przykład
__hash__()
. Bardziej ogólnie, patrz en.wikipedia.org/wiki/Hash_function
id(object)
jest 16x wynik z object.__hash__()
. Tak więc fragment glosariusza jest niepoprawny dla tej wersji - wartość skrótu nie jest id()
, ale pochodzi z niej (jak rzeczywiście zauważono w zaktualizowanych dokumentach dla Pythona 2.7.12).
hash((1, [2, 3]))
zobaczyć to w akcji. Wysłałem prośbę o poprawienie hasła w haszowaniu.
Wszystkie odpowiedzi tutaj mają dobre objaśnienie funkcjonalne obiektów w Pythonie, ale uważam, że najpierw należy zrozumieć pojęcie Hashing.
Hashing to koncepcja informatyki, która służy do tworzenia wysokowydajnych struktur danych o pseudolosowym dostępie, w których duża ilość danych ma być szybko przechowywana i dostępna.
Na przykład, jeśli masz 10 000 numerów telefonów i chcesz je przechowywać w tablicy (która jest sekwencyjną strukturą danych, która przechowuje dane w sąsiadujących lokalizacjach pamięci i zapewnia losowy dostęp), ale możesz nie mieć wymaganej ilości ciągłych lokalizacje pamięci.
Możesz więc zamiast tego użyć tablicy o rozmiarze 100 i użyć funkcji skrótu, aby odwzorować zestaw wartości na te same indeksy, a te wartości można zapisać na połączonej liście. Zapewnia to wydajność podobną do tablicy.
Teraz funkcja skrótu może być tak prosta, jak dzielenie liczby z rozmiarem tablicy i przyjmowanie reszty jako indeksu.
Aby uzyskać więcej informacji, zobacz https://en.wikipedia.org/wiki/Hash_function
Oto kolejna dobra referencja: http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html
Wszystko, czego nie można modyfikować (środki, które mogą ulec zmianie) mogą zostać zaszyfrowane. Oprócz funkcji skrótu do wyszukania, jeśli klasa ją ma, np. dir(tuple)
i szukając __hash__
metody, oto kilka przykładów
#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
Lista niezmiennych typów:
int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
Lista zmiennych typów:
list, dict, set, bytearray, user-defined classes
Ellipsis
jest to również niezmienny typ i może być używany jako klucz do dict
.
hash(MyClass)
__hash__
i __eq__
. Co więcej, wszystkie klasy zdefiniowane przez użytkownika implementują te metody (a zatem są haszowalne), ponieważ dziedziczą one metody object
(uniwersalna klasa bazowa).
W moim rozumieniu, zgodnie ze słownikiem Pythona, podczas tworzenia instancji obiektów, które można mieszać, niezmienna wartość jest również obliczana na podstawie elementów lub wartości instancji. Na przykład tę wartość można następnie wykorzystać jako klucz w nagraniu, jak poniżej:
>>> 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'
możemy stwierdzić, że wartość skrótu tuple_a i tuple_c są takie same, ponieważ mają tych samych członków. Kiedy używamy tuple_a jako klucza w dict_a, możemy stwierdzić, że wartość dla dict_a [tuple_c] jest taka sama, co oznacza, że gdy są używane jako klucz w dict, zwracają tę samą wartość, ponieważ wartości skrótu są to samo. W przypadku obiektów, które nie są haszowalne, skrót mieszający jest zdefiniowany jako Brak:
>>> type(dict.__hash__)
<class 'NoneType'>
Wydaje mi się, że ta wartość skrótu jest obliczana przy inicjalizacji instancji, a nie w sposób dynamiczny, dlatego hahowalne są tylko niezmienne obiekty. Mam nadzieję że to pomoże.
Pozwól, że dam ci działający przykład na zrozumienie obiektów możliwych do skrótu w Pythonie. Biorę 2 Tuple dla tego przykładu. Każda wartość w krotce ma unikalną wartość skrótu, która nigdy nie zmienia się w trakcie jej życia. Na tej podstawie ma wartość, porównanie dwóch krotek jest wykonywane. Możemy uzyskać wartość skrótu elementu krotkowego za pomocą Id ().
W pythonie oznacza to, że obiekt może być składnikiem zestawu w celu zwrócenia indeksu. Oznacza to, że mają unikalną tożsamość / identyfikator.
na przykład w python 3.3:
struktura danych Listy nie są haszowalne, ale struktura danych Krotki są haszowalne.
id
, co (przybliżony) adres obiektu w pamięci.
Hashable = możliwość skrócenia.
Ok, co to jest hashowanie? Funkcja skrótu to funkcja, która pobiera obiekt, wypowiada ciąg taki jak „Python” i zwraca kod o stałym rozmiarze. Dla uproszczenia załóżmy, że zwracana wartość jest liczbą całkowitą.
Po uruchomieniu skrótu („Python”) w Pythonie 3 otrzymuję 5952713340227947791. Różne wersje Pythona mogą swobodnie zmieniać podstawową funkcję skrótu, więc prawdopodobnie otrzymasz inną wartość. Ważne jest to, że bez względu na to, ile razy teraz uruchamiam hash („Python”), zawsze otrzymam ten sam wynik z tą samą wersją Pythona.
Ale skrót („Java”) zwraca 1753925553814008565. Jeśli więc zmieniam obiekt, który zmieniam, zmienia się również wynik. Z drugiej strony, jeśli obiekt będący skrótem nie zmienia się, wynik pozostaje ten sam.
Dlaczego to ma znaczenie?
Na przykład słowniki Pythona wymagają, aby klucze były niezmienne. Oznacza to, że klucze muszą być obiektami, które się nie zmieniają. W Pythonie ciągi są niezmienne, podobnie jak inne podstawowe typy (int, float, bool). Krotki i frozensety są również niezmienne. Z drugiej strony, listy nie są niezmienne (tzn. Są zmienne), ponieważ można je zmienić. Podobnie, dyktanda są zmienne.
Kiedy więc mówimy, że coś da się ukryć, mamy na myśli to, że jest niezmienne. Jeśli spróbuję przekazać zmienny typ do funkcji hash (), zakończy się ona niepowodzeniem:
>>> 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
W Pythonie każdy niezmienny obiekt (taki jak liczba całkowita, wartość logiczna, łańcuch, krotka) jest mieszalny, co oznacza, że jego wartość nie zmienia się w trakcie jego życia. Umożliwia to Pythonowi utworzenie unikatowej wartości skrótu w celu jej identyfikacji, która może być używana przez słowniki do śledzenia unikatowych kluczy i zestawów do śledzenia unikalnych wartości.
Właśnie dlatego Python wymaga, abyśmy używali niezmiennych typów danych dla kluczy w słowniku.
Aby utworzyć tabelę skrótów od zera, wszystkie wartości należy ustawić na „Brak” i zmodyfikować, gdy pojawi się wymaganie. Obiekty haszujące odnoszą się do modyfikowalnych typów danych (słownik, listy itp.). Z drugiej strony zestawów nie można ponownie zainicjować po przypisaniu, więc zestawów nie można haszować. Natomiast wariant set () - frozenset () - podlega skróceniu.
__hash__()
metody .