''' mbinary ######################################################################### # File : hashTable.py # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-07-08 16:39 # Description: ######################################################################### ''' class item: def __init__(self,key,val,nextItem=None): self.key = key self.val = val self.next = nextItem def to(self,it): self.next = it def __eq__(self,it): '''using keyword ''' return self.key == it.key def __bool__(self): return self.key is not None def __str__(self): li = [] nd = self while nd: li.append(f'({nd.key}:{nd.val})') nd = nd.next return ' -> '.join(li) def __repr__(self): return f'item({self.key},{self.val})' class hashTable: def __init__(self,size=100): self.size = size self.slots=[item(None,None) for i in range(self.size)] def __setitem__(self,key,val): nd = self.slots[self.myhash(key)] while nd.next: if nd.key ==key: if nd.val!=val: nd.val=val return nd = nd.next nd.next = item(key,val) def myhash(self,key): if isinstance(key,str): key = sum(ord(i) for i in key) if not isinstance(key,int): key = hash(key) return key % self.size def __iter__(self): '''when using keyword , such as ' if key in dic', the dic's __iter__ method will be called,(if hasn't, calls __getitem__ then ~iterate~ dic's keys to compare whether one equls to the key ''' for nd in self.slots: nd = nd.next while nd : yield nd.key nd = nd.next def __getitem__(self,key): nd =self.slots[ self.myhash(key)].next while nd: if nd.key==key: return nd.val nd = nd.next raise Exception(f'[KeyError]: {self.__class__.__name__} has no key {key}') def __delitem__(self,key): '''note that None item and item(None,None) differ with each other, which means you should take care of them and correctly cop with None item especially when deleting items ''' n = self.myhash(key) nd = self.slots[n].next if nd.key == key: if nd.next is None: self.slots[n] = item(None,None) # be careful else:self.slots[n] = nd.next return while nd: if nd.next is None: break # necessary if nd.next.key ==key: nd.next = nd.next.next nd = nd.next def __str__(self): li = ['\n\n'+'-'*5+'hashTable'+'-'*5] for i,nd in enumerate(self.slots): li.append(f'{i}: '+str(nd.next)) return '\n'.join(li) if __name__ =='__main__': from random import randint dic = hashTable(16) n = 100 li = [1,2,5,40,324,123,6,22,18,34,50] print(f'build hashTable using {li}') for i in li: dic[i] = '$'+str(i) print(dic) for i in [1,34,45,123]: if i in dic: print(f'{i} in dic, deleting it') del dic[i] else: print(f'{i} not in dic, ignore it') print(dic) print(f'dic[2] is {dic[2]}') try: dic[-1] except Exception as e: print(e)