dsa.hashtable

Module containing hash table class.

  1""" Module containing hash table class. """
  2
  3class HashTable:
  4    """ 
  5    A hashtable implementation. 
  6    """
  7    def __init__(self, capacity=20):
  8        """
  9        Initialize a hashtable with a given capacity.
 10
 11        Args:
 12            capacity: The capacity of the hashtable.
 13        """
 14        self.capacity = capacity
 15
 16        self.array = []
 17        for _ in range(self.capacity):
 18            self.array.append([])
 19
 20        #: the number of items in the hashtable
 21        self.count = 0
 22        
 23    def hash_function(self, key) -> int:
 24        """ 
 25        Return a hash value based on a given key. 
 26
 27        Args:
 28            key: The key to convert to a hashvalue.
 29        Returns:
 30            Hash value modded to the hashtable capacity.
 31        """
 32        mult = 31
 33        hash_val = 0
 34        for character in str(key):
 35            hash_val *= mult
 36            hash_val += ord(character)
 37            hash_val %= (2**32)
 38
 39        return hash_val % self.capacity
 40        
 41    def key_exists(self, key) -> bool:
 42        """ 
 43        Returns a Boolean on whether a key exists in the hashtable or not .
 44
 45        Args:
 46            key: The key to check for in the hashtable.
 47        Returns:
 48            Boolean of key existence.
 49        """
 50        bucket = self.hash_function(key)
 51        
 52        for e in self.array[bucket]:
 53            if e[0] == key:
 54                return True
 55        return False
 56
 57    def set(self, key, value):
 58        """ 
 59        Set a key-value pair in the hashtable.
 60
 61        If key exists, replace the value otherwise, create a new key-pair.
 62
 63        Args:
 64            key: The key to check for.
 65            value: The value to set or create.
 66        """
 67
 68        bucket = self.hash_function(key)
 69
 70        # linear searh for key 
 71        for e in self.array[bucket]:
 72            if e[0] == key:
 73                e[1] = value
 74                break
 75        else:
 76            self.array[bucket].append([ key, value ])
 77            self.count += 1
 78
 79    def get(self, key):
 80        """ 
 81        Get corresponding value of a given key in the hash table.
 82
 83        Args:
 84            key: The key to check for.
 85            value: The value to set or create.
 86        Returns:
 87            corresponding value of key.
 88            None if key is not found.
 89        """
 90        bucket = self.hash_function(key)
 91
 92        for e in self.array[bucket]:
 93            if e[0] == key:
 94                return e[1]
 95
 96        return None
 97
 98    def remove(self, key):
 99        """
100        Remove key-value pair if specified key is found. Raise KeyError if not found.
101
102        Args:
103            key: The key to check for.
104        Raises:
105            KeyError: If the key is not found in the hashtable.
106        """
107        bucket = self.hash_function(key)
108        for i in range(len(self.array[bucket])):
109            kvpair = self.array[bucket][i]
110            if kvpair and kvpair[0] == key:
111                del self.array[bucket][i]
112                self.count -= 1
113                return
114        raise KeyError(key)
115    
116    def __repr__(self):
117        """
118        Return a string representation of the hashtable.
119        """
120        s = "{"
121        pairs = []
122        for bucket in self.array:
123            if bucket:
124                for chain_link in bucket:
125                    pairs.append(f"{chain_link[0]}:{chain_link[1]}")
126        s += ", ".join(pairs)
127        return s + "}"
128
129    def show_buckets(self):
130        """
131        Return a string displaying the contents of all buckets in the hashtable.
132        """
133        s = ""
134        for i, bucket in enumerate(self.array):
135            s += f"Bucket {i}: {bucket}\n"
136        return s
137    
138    def __len__(self):
139        """
140        Return the number of items in the hashtable.
141        """
142        return self.count
143    
144    def __getitem__(self, key):
145        """
146        Get the value associated with the key using indexing.
147
148        Args:
149            key: The key to look up.
150        Returns:
151            The value associated with the key.
152        """
153        return self.get(key)
154    
155    def __setitem__(self, key, value):
156        """
157        Set the value associated with the key using indexing.
158
159        Args:
160            key: The key to set.
161            value: The value to associate with the key.
162        """
163        self.set(key, value)
164
165    def __delitem__(self, key):
166        """
167        Remove the key-value pair associated with the key using indexing.
168
169        Args:
170            key: The key to remove.
171        """
172        self.remove(key)
173
174    def __contains__(self, key):
175        """
176        Check if the key exists in the hashtable using 'in' operator.
177
178        Args:
179            key: The key to check for existence.
180        Returns:
181            True if key exists, False otherwise.
182        """
183        return self.key_exists(key)
184    
185    def pop(self, key, default=None):
186        """
187        Remove specified key and return the value.
188        If key is not found, return default.
189        """
190        bucket = self.hash_function(key)
191        for i, kvpair in enumerate(self.array[bucket]):
192            if kvpair and kvpair[0] == key:
193                value = kvpair[1]
194                del self.array[bucket][i]
195                self.count -= 1
196                return value
197        return default
198        
199    def enumerate(self):
200        """
201        Return the enumeration of key-value pairs in the hashtable.
202
203        Returns:
204            Enumeration of key-value pairs.
205        """
206        pairs = []
207        for bucket in self.array:
208            for chain_link in bucket:
209                pairs.append(chain_link)
210        return enumerate(pairs)
211    
212    def __eq__(self, other):
213        """
214        Compare this hashtable to another for equality.
215
216        Args:
217            other: The object to compare with.
218
219        Returns:
220            True if both are HashTable instances and their key-value pairs are equal, False otherwise.
221        """
222        if not isinstance(other, HashTable):
223            return False
224        def to_dict(ht):
225            d = {}
226            for bucket in ht.array:
227                for chain_link in bucket:
228                    d[chain_link[0]] = chain_link[1]
229            return d
230        return to_dict(self) == to_dict(other)
231    
232    def __iter__(self):
233        """
234        Iterate over all keys in the hashtable.
235        """
236        for bucket in self.array:
237            for chain_link in bucket:
238                yield chain_link[0]
class HashTable:
  4class HashTable:
  5    """ 
  6    A hashtable implementation. 
  7    """
  8    def __init__(self, capacity=20):
  9        """
 10        Initialize a hashtable with a given capacity.
 11
 12        Args:
 13            capacity: The capacity of the hashtable.
 14        """
 15        self.capacity = capacity
 16
 17        self.array = []
 18        for _ in range(self.capacity):
 19            self.array.append([])
 20
 21        #: the number of items in the hashtable
 22        self.count = 0
 23        
 24    def hash_function(self, key) -> int:
 25        """ 
 26        Return a hash value based on a given key. 
 27
 28        Args:
 29            key: The key to convert to a hashvalue.
 30        Returns:
 31            Hash value modded to the hashtable capacity.
 32        """
 33        mult = 31
 34        hash_val = 0
 35        for character in str(key):
 36            hash_val *= mult
 37            hash_val += ord(character)
 38            hash_val %= (2**32)
 39
 40        return hash_val % self.capacity
 41        
 42    def key_exists(self, key) -> bool:
 43        """ 
 44        Returns a Boolean on whether a key exists in the hashtable or not .
 45
 46        Args:
 47            key: The key to check for in the hashtable.
 48        Returns:
 49            Boolean of key existence.
 50        """
 51        bucket = self.hash_function(key)
 52        
 53        for e in self.array[bucket]:
 54            if e[0] == key:
 55                return True
 56        return False
 57
 58    def set(self, key, value):
 59        """ 
 60        Set a key-value pair in the hashtable.
 61
 62        If key exists, replace the value otherwise, create a new key-pair.
 63
 64        Args:
 65            key: The key to check for.
 66            value: The value to set or create.
 67        """
 68
 69        bucket = self.hash_function(key)
 70
 71        # linear searh for key 
 72        for e in self.array[bucket]:
 73            if e[0] == key:
 74                e[1] = value
 75                break
 76        else:
 77            self.array[bucket].append([ key, value ])
 78            self.count += 1
 79
 80    def get(self, key):
 81        """ 
 82        Get corresponding value of a given key in the hash table.
 83
 84        Args:
 85            key: The key to check for.
 86            value: The value to set or create.
 87        Returns:
 88            corresponding value of key.
 89            None if key is not found.
 90        """
 91        bucket = self.hash_function(key)
 92
 93        for e in self.array[bucket]:
 94            if e[0] == key:
 95                return e[1]
 96
 97        return None
 98
 99    def remove(self, key):
100        """
101        Remove key-value pair if specified key is found. Raise KeyError if not found.
102
103        Args:
104            key: The key to check for.
105        Raises:
106            KeyError: If the key is not found in the hashtable.
107        """
108        bucket = self.hash_function(key)
109        for i in range(len(self.array[bucket])):
110            kvpair = self.array[bucket][i]
111            if kvpair and kvpair[0] == key:
112                del self.array[bucket][i]
113                self.count -= 1
114                return
115        raise KeyError(key)
116    
117    def __repr__(self):
118        """
119        Return a string representation of the hashtable.
120        """
121        s = "{"
122        pairs = []
123        for bucket in self.array:
124            if bucket:
125                for chain_link in bucket:
126                    pairs.append(f"{chain_link[0]}:{chain_link[1]}")
127        s += ", ".join(pairs)
128        return s + "}"
129
130    def show_buckets(self):
131        """
132        Return a string displaying the contents of all buckets in the hashtable.
133        """
134        s = ""
135        for i, bucket in enumerate(self.array):
136            s += f"Bucket {i}: {bucket}\n"
137        return s
138    
139    def __len__(self):
140        """
141        Return the number of items in the hashtable.
142        """
143        return self.count
144    
145    def __getitem__(self, key):
146        """
147        Get the value associated with the key using indexing.
148
149        Args:
150            key: The key to look up.
151        Returns:
152            The value associated with the key.
153        """
154        return self.get(key)
155    
156    def __setitem__(self, key, value):
157        """
158        Set the value associated with the key using indexing.
159
160        Args:
161            key: The key to set.
162            value: The value to associate with the key.
163        """
164        self.set(key, value)
165
166    def __delitem__(self, key):
167        """
168        Remove the key-value pair associated with the key using indexing.
169
170        Args:
171            key: The key to remove.
172        """
173        self.remove(key)
174
175    def __contains__(self, key):
176        """
177        Check if the key exists in the hashtable using 'in' operator.
178
179        Args:
180            key: The key to check for existence.
181        Returns:
182            True if key exists, False otherwise.
183        """
184        return self.key_exists(key)
185    
186    def pop(self, key, default=None):
187        """
188        Remove specified key and return the value.
189        If key is not found, return default.
190        """
191        bucket = self.hash_function(key)
192        for i, kvpair in enumerate(self.array[bucket]):
193            if kvpair and kvpair[0] == key:
194                value = kvpair[1]
195                del self.array[bucket][i]
196                self.count -= 1
197                return value
198        return default
199        
200    def enumerate(self):
201        """
202        Return the enumeration of key-value pairs in the hashtable.
203
204        Returns:
205            Enumeration of key-value pairs.
206        """
207        pairs = []
208        for bucket in self.array:
209            for chain_link in bucket:
210                pairs.append(chain_link)
211        return enumerate(pairs)
212    
213    def __eq__(self, other):
214        """
215        Compare this hashtable to another for equality.
216
217        Args:
218            other: The object to compare with.
219
220        Returns:
221            True if both are HashTable instances and their key-value pairs are equal, False otherwise.
222        """
223        if not isinstance(other, HashTable):
224            return False
225        def to_dict(ht):
226            d = {}
227            for bucket in ht.array:
228                for chain_link in bucket:
229                    d[chain_link[0]] = chain_link[1]
230            return d
231        return to_dict(self) == to_dict(other)
232    
233    def __iter__(self):
234        """
235        Iterate over all keys in the hashtable.
236        """
237        for bucket in self.array:
238            for chain_link in bucket:
239                yield chain_link[0]

A hashtable implementation.

HashTable(capacity=20)
 8    def __init__(self, capacity=20):
 9        """
10        Initialize a hashtable with a given capacity.
11
12        Args:
13            capacity: The capacity of the hashtable.
14        """
15        self.capacity = capacity
16
17        self.array = []
18        for _ in range(self.capacity):
19            self.array.append([])
20
21        #: the number of items in the hashtable
22        self.count = 0

Initialize a hashtable with a given capacity.

Args: capacity: The capacity of the hashtable.

capacity
array
count
def hash_function(self, key) -> int:
24    def hash_function(self, key) -> int:
25        """ 
26        Return a hash value based on a given key. 
27
28        Args:
29            key: The key to convert to a hashvalue.
30        Returns:
31            Hash value modded to the hashtable capacity.
32        """
33        mult = 31
34        hash_val = 0
35        for character in str(key):
36            hash_val *= mult
37            hash_val += ord(character)
38            hash_val %= (2**32)
39
40        return hash_val % self.capacity

Return a hash value based on a given key.

Args: key: The key to convert to a hashvalue. Returns: Hash value modded to the hashtable capacity.

def key_exists(self, key) -> bool:
42    def key_exists(self, key) -> bool:
43        """ 
44        Returns a Boolean on whether a key exists in the hashtable or not .
45
46        Args:
47            key: The key to check for in the hashtable.
48        Returns:
49            Boolean of key existence.
50        """
51        bucket = self.hash_function(key)
52        
53        for e in self.array[bucket]:
54            if e[0] == key:
55                return True
56        return False

Returns a Boolean on whether a key exists in the hashtable or not .

Args: key: The key to check for in the hashtable. Returns: Boolean of key existence.

def set(self, key, value):
58    def set(self, key, value):
59        """ 
60        Set a key-value pair in the hashtable.
61
62        If key exists, replace the value otherwise, create a new key-pair.
63
64        Args:
65            key: The key to check for.
66            value: The value to set or create.
67        """
68
69        bucket = self.hash_function(key)
70
71        # linear searh for key 
72        for e in self.array[bucket]:
73            if e[0] == key:
74                e[1] = value
75                break
76        else:
77            self.array[bucket].append([ key, value ])
78            self.count += 1

Set a key-value pair in the hashtable.

If key exists, replace the value otherwise, create a new key-pair.

Args: key: The key to check for. value: The value to set or create.

def get(self, key):
80    def get(self, key):
81        """ 
82        Get corresponding value of a given key in the hash table.
83
84        Args:
85            key: The key to check for.
86            value: The value to set or create.
87        Returns:
88            corresponding value of key.
89            None if key is not found.
90        """
91        bucket = self.hash_function(key)
92
93        for e in self.array[bucket]:
94            if e[0] == key:
95                return e[1]
96
97        return None

Get corresponding value of a given key in the hash table.

Args: key: The key to check for. value: The value to set or create. Returns: corresponding value of key. None if key is not found.

def remove(self, key):
 99    def remove(self, key):
100        """
101        Remove key-value pair if specified key is found. Raise KeyError if not found.
102
103        Args:
104            key: The key to check for.
105        Raises:
106            KeyError: If the key is not found in the hashtable.
107        """
108        bucket = self.hash_function(key)
109        for i in range(len(self.array[bucket])):
110            kvpair = self.array[bucket][i]
111            if kvpair and kvpair[0] == key:
112                del self.array[bucket][i]
113                self.count -= 1
114                return
115        raise KeyError(key)

Remove key-value pair if specified key is found. Raise KeyError if not found.

Args: key: The key to check for. Raises: KeyError: If the key is not found in the hashtable.

def show_buckets(self):
130    def show_buckets(self):
131        """
132        Return a string displaying the contents of all buckets in the hashtable.
133        """
134        s = ""
135        for i, bucket in enumerate(self.array):
136            s += f"Bucket {i}: {bucket}\n"
137        return s

Return a string displaying the contents of all buckets in the hashtable.

def pop(self, key, default=None):
186    def pop(self, key, default=None):
187        """
188        Remove specified key and return the value.
189        If key is not found, return default.
190        """
191        bucket = self.hash_function(key)
192        for i, kvpair in enumerate(self.array[bucket]):
193            if kvpair and kvpair[0] == key:
194                value = kvpair[1]
195                del self.array[bucket][i]
196                self.count -= 1
197                return value
198        return default

Remove specified key and return the value. If key is not found, return default.

def enumerate(self):
200    def enumerate(self):
201        """
202        Return the enumeration of key-value pairs in the hashtable.
203
204        Returns:
205            Enumeration of key-value pairs.
206        """
207        pairs = []
208        for bucket in self.array:
209            for chain_link in bucket:
210                pairs.append(chain_link)
211        return enumerate(pairs)

Return the enumeration of key-value pairs in the hashtable.

Returns: Enumeration of key-value pairs.