The HashTable class provides a dictionary-like data structure that uses a hash function to map keys to values. It handles collisions using chaining (storing multiple key-value pairs in the same bucket using lists).
The HashTable uses a polynomial rolling hash function with a multiplier of 31 and supports dynamic key-value storage with O(1) average-case lookup time.
from dsa.hashtable import HashTable# Create a hashtable with default capacity of 20ht = HashTable()# Create a hashtable with custom capacityht = HashTable(capacity=50)
Parameters:
capacity (int, optional): The initial capacity of the hashtable. Defaults to 20.
Insert or update a key-value pair in the hashtable.
ht = HashTable()# Insert new key-value pairsht.set("name", "Alice")ht.set("age", 25)ht.set("city", "New York")# Update existing valueht.set("age", 26) # Updates age from 25 to 26
Parameters:
key: The key to insert or update
value: The value to associate with the key
Time Complexity: O(1) average case, O(n) worst case
ht = HashTable()ht.set("name", "Alice")if ht.key_exists("name"): print("Name exists") # This will printif not ht.key_exists("email"): print("Email not found") # This will print
Parameters:
key: The key to check
Returns:True if key exists, False otherwiseTime Complexity: O(1) average case, O(n) worst case
The HashTable implements several magic methods for intuitive Python integration:
Indexing
Membership
Length
Iteration
Equality
ht = HashTable()# Set values using indexinght["name"] = "Alice"ht["age"] = 25# Get values using indexingname = ht["name"] # "Alice"age = ht["age"] # 25# Delete using indexingdel ht["age"]
ht = HashTable()ht["name"] = "Alice"ht["age"] = 25# Check membership with 'in' operatorif "name" in ht: print("Name exists")if "email" not in ht: print("Email not found")
ht = HashTable()ht["name"] = "Alice"ht["age"] = 25ht["city"] = "New York"# Get number of itemscount = len(ht) # Returns 3
ht = HashTable()ht["name"] = "Alice"ht["age"] = 25ht["city"] = "New York"# Iterate over keysfor key in ht: print(f"{key}: {ht[key]}")
ht1 = HashTable()ht1["name"] = "Alice"ht1["age"] = 25ht2 = HashTable()ht2["age"] = 25ht2["name"] = "Alice"# Compare hashtablesif ht1 == ht2: print("Hashtables are equal") # This will print
from dsa.hashtable import HashTable# Create a small hashtable to demonstrate collision handlinght = HashTable(capacity=5)# Add multiple items that may hash to the same bucketht["cat"] = 1ht["act"] = 2 # Anagram - might collideht["tac"] = 3 # Anagram - might collideht["dog"] = 4ht["god"] = 5 # Anagram - might collideprint(f"Total items: {len(ht)}")print(ht.show_buckets()) # Shows how items are distributed across buckets# All items are still accessible despite collisionsfor key in ht: print(f"{key}: {ht[key]}")
The worst-case scenario occurs when all keys collide and hash to the same bucket, resulting in linear search through the chain. Choose an appropriate initial capacity to minimize collisions.