Sobes.tech
Junior

Wat is een hash en hoe wordt het gebruikt in woordenboeken in Python?

sobes.tech AI

Antwoord van AI

Hash (of hash-waarde) is een numerieke waarde van vaste lengte die wordt berekend op basis van de inhoud van een object met behulp van een hashfunctie. Een goede hashfunctie garandeert determinisme (hetzelfde object geeft altijd dezelfde hash) en streeft naar een gelijke verdeling van hashes voor verschillende objecten.

In Python gebruiken woordenboeken (type dict) hashing om efficiënt paren "sleutel-waarde" op te slaan en te zoeken. Sleutels moeten hashbaar zijn, dat wil zeggen, de methode __hash__() moeten bezitten en onveranderlijk zijn of een implementatie van __eq__() en __hash__() hebben die garandeert dat gelijkwaardige objecten dezelfde hash hebben.

Proces van werking van een woordenboek met hashes:

  1. Invoegen: Bij het toevoegen van een paar (sleutel, waarde) wordt de hash van de sleutel berekend. Op basis van de hash wordt een geschatte plek (emmer of "bucket") bepaald om dit paar in het geheugen op te slaan. Als meerdere sleutels dezelfde hash hebben (botsing), worden de paren in die emmer opgeslagen, vaak in de vorm van een gekoppelde lijst of een ander mechanisme voor het oplossen van botsingen.
  2. Zoeken: Bij het zoeken van een waarde op basis van een sleutel wordt de hash van de meegegeven sleutel berekend. Met behulp van de hash vindt het woordenboek snel de juiste emmer. Vervolgens worden binnen die emmer de sleutels vergeleken (met behulp van de methode __eq__) om de juiste sleutel te vinden en de bijbehorende waarde op te halen.

Voordelen van hashing:

  • Efficiëntie: Gemiddeld worden invoeg-, verwijder- en zoekbewerkingen in een woordenboek uitgevoerd met een constante tijdcomplexiteit O(1), ongeacht de grootte van het woordenboek.
  • Snelle toegang: Hash maakt het mogelijk snel naar de vermoedelijke locatie van gegevens te gaan, zonder alle elementen te doorzoeken.

Beperkingen en kenmerken:

  • Hashbare sleutels: Zoals vermeld, moeten sleutels hashbaar zijn. Veranderlijke typen, zoals lijsten (list) en verzamelingen (set), zijn standaard niet hashbaar en kunnen niet als sleutels worden gebruikt.
  • Botsingen: Hoewel hashfuncties proberen botsingen te minimaliseren, kunnen ze voorkomen, wat de operaties in het slechtste geval iets kan vertragen (beïnvloedt de constante in O(1)).
  • Volgorde: Tot Python 3.7 hing de volgorde van elementen in een woordenboek af van de volgorde van invoer en de hashes van de sleutels. Vanaf Python 3.7 behouden woordenboeken de invoerorde van sleutels als een neveneffect van de implementatie, maar dit is geen onderdeel van het hashmechanisme.

Voorbeeld van een hashbaar en niet-hashbaar object:

# Hashbaar object (onveranderlijk)
string_key = "hallo"
int_key = 123
tuple_key = (1, 2)

print(hash(string_key))
print(hash(int_key))
print(hash(tuple_key))

# Niet-hashbaar object (veranderlijk)
list_key = [1, 2]
# print(hash(list_key)) # Dit veroorzaakt een TypeError

# Voorbeeld van gebruik in een woordenboek
my_dict = {
    string_key: "wereld",
    int_key: 456,
    tuple_key: "een tuple"
}

print(my_dict[string_key])
print(my_dict[int_key])
print(my_dict[tuple_key])

Dus, hash is een fundamenteel mechanisme dat het mogelijk maakt voor Python-woordenboeken om hoge prestaties te bereiken in hun operaties, gebaseerd op snelle berekening van de numerieke representatie van de sleutel.