模拟dict

class Array(object):
   def __init__(self,size=64,init=None):
      self._size = size
      self._items = [init] * size

   def __getitem__(self,index):
      return self._items[index]

   def __setitem__(self, index, value):
       self._items[index] = value

   def __len__(self):
      return self._size(self)

   def clear(self,value=None):
      for i in range(self._items):
         self._items[i] = value

   def __iter__(self):
      for item in self._items:
         yield item

class Slot(object):
   def __init(self,key,value):
      self.key,self,value = key,value

class HashTable(object):
   UNUESD = None
   EMPTY = None

   def __init__(self):
      self._table = Array(8,init=HashTable.UNUESD)
      self.length = 0

   @property
   def _load_factor(self):
      return self.length / float(len(self._table))

   def __len__(self):
      return self.length

   def __hash(self,key):
      return abs(hash(key)) % len(self._table)

   def _find_key(self,key):
      index = self.__hash(key)
      _len = len(self._table)
      while self._table[index] is not HashTable.UNUESD:
         if self._table[index] is HashTable.EMPTY:
            index = (index*5 +1) % _len
            continue
         elif self._table[index].key == key:
            return index
         else:
            index = (index*5 + 1) %_len
         return None
   def _slot_can_insert(self,index):
      return (self._table[index] is HashTable.EMPTY
              or self.table[index] is HashTable.UNUESD)

   def _find_slot_for_insert(self,key):
      index = self.__hash(key)
      _len = len(self._table)
      while not self._slot_can_insert(index):
         index = (index * 5 + 1) % _len
      return index

   def __cantains__(self,key):
      index = self._find_key(key)
      return index is not None

   def add(self,key,value):
      if key in self:
         index = self._find_key(key)
         self._table[index].value = value
         return False
      else:
         index = self._find_slot_for_insert(key)
         self._table[index] = Slot(key,value)
         self.length += 1
         if self._load_factor > 0.8:
            self._rehash()
         return True

   def _rehash(self):
      old_table = self._table
      newsize = len(self._table) *2
      self._table = Array(newsize,HashTable.UNUESD)
      self.length = 0

      if Slot is not HashTable.UNUESD and Slot is not HashTable.EMPTY:
         index = self._find_slot_for_insert(Slot.key)
         self._table[index] = Slot
         self.length += 1

   def get(self,key,default=None):
      index = self._find_key(key)
      if index is None:
         return default
      else:
         return self._table[index].value

   def remove(self,key):
      index = self._find_key(key)
      if index is None:
         raise Exception('keyError!!!!')
      value = self._table[index].vlaue
      self.length -= 1
      self._table[index] = HashTable.EMPTY
      return value

   def __iter__(self):
      for slot in self._table:
         if slot not in (HashTable.EMPTY,HashTable.UNUESD):
            yield slot.key

class DictADT(HashTable):

    def __setitem__(self,key,value):
        self.add(key,value)

    def __getitem__(self,key):
        if key not in self:
            raise Exception('Key Error')
        else:
            return self.get(key)
        
    def _iter_slot(self):
        for slot in self._table:
            if slot not in (HashTable.UNUESD,HashTable.EMPTY):
                yield slot
    
    def items(self):
        for slot in self._iter_slot():
            yield (slot.key,slot.value)
        
    def keys(slef):
        for slot in self._iter_slot():
            yield slot.key
    
    def values(self):
        for slot in self._iter_slot():
            yield slot.value
   
posted @ 2020-04-13 09:28  ColaIce  阅读(130)  评论(0)    收藏  举报