Created
August 1, 2022 20:58
-
-
Save Sigmanificient/3d5ee8066ff7ce6a2de160136f85843b to your computer and use it in GitHub Desktop.
Implementation of a hahmap in python (dict equivalent)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
from dataclasses import dataclass | |
from typing import Any, Optional, List, Generic, TypeVar, NoReturn, Callable, Union, Tuple | |
_K = TypeVar('_K') | |
_V = TypeVar('_V') | |
@dataclass | |
class LinkedList: | |
key: Optional[_K] | |
val: Optional[_V] | |
next_: Optional[LinkedList] | |
def __repr__(self): | |
self_repr = f'({self.key!r}, {self.val!r})' | |
return self_repr if self.next_ is None else f'{self_repr} -> {self.next_}' | |
class Hashmap(Generic[_K, _V]): | |
_Missing: object = type('_Missing', (), {}) | |
_SIZE = 64 | |
def __init__(self): | |
self.__pool: List[LinkedList] = [ | |
LinkedList(None, None, None) | |
for _ in range(self._SIZE) | |
] | |
def __get_hash(self, key: _K) -> int: | |
return hash(key) % self._SIZE | |
def __getitem__(self, key: _K) -> _V: | |
item = self.__pool[self.__get_hash(key)] | |
while item.key != key and item.next_: | |
item = item.next_ | |
if item.key is None: | |
raise KeyError(f'Key {key} not found in Hashmap') | |
return item.val | |
def __setitem__(self, key: _K, val: _V) -> NoReturn: | |
h = self.__get_hash(key) | |
item = self.__pool[h] | |
if item.val is None: | |
self.__pool[h].key = key | |
self.__pool[h].val = val | |
return | |
while item.next_: | |
item = item.next_ | |
item.next_ = LinkedList(key, val, None) | |
def __repr__(self) -> str: | |
inner = '\n\t'.join(map(str, self.__pool)) | |
return f"Hashmap(\n\t{inner}\n)" | |
Item = Union[_K, _V, Tuple[_K, _V]] | |
Take = Callable[[LinkedList], Item] | |
def __iter_keep(self, func: Take) -> Item: | |
result = [] | |
for item in self.__pool: | |
while item is not None: | |
result.append(func(item)) | |
item = item.next_ | |
return result | |
def keys(self) -> List[_K]: | |
return self.__iter_keep(lambda item: item.key) | |
def values(self) -> List[_V]: | |
return self.__iter_keep(lambda item: item.val) | |
def items(self) -> List[Tuple[_K, _V]]: | |
return self.__iter_keep(lambda item: (item.key, item.val)) | |
def main(): | |
hashmap: Hashmap[str] = Hashmap() | |
for c, l in enumerate('zyxwvutsrqponmlkjihgfedcba'): | |
hashmap[c] = l | |
print(hashmap) | |
print(hashmap.keys()) | |
print(hashmap.values()) | |
print(hashmap.items()) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment