中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python 哈希表實現簡單python字典代碼實例

發布時間:2020-09-29 00:02:11 來源:腳本之家 閱讀:186 作者:DRQ丶 欄目:開發技術

這篇文章主要介紹了python 哈希表實現簡單python字典代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

class Array(object):
  def __init__(self, size = 32, 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
  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):
  """
  定義一個哈希表數組的槽
  注意:一個槽有三種狀態
  1. 從未被使用過,HashMap.UNUSED。 此槽沒有被使用和沖突過,查找時只要找到UNUSED 就不用再繼續探查了
  2. 使用過但是remove了, 此時是HashMap.EMPTY,該談差點后面的元素仍可能是有key
  3. 槽正在使用Slot 節點
  """
  def __init__(self, key, value):
    self.key = key
    self.value = value
class HashTable(object):
  UNUSED = None # 表示slot 沒有被使用過
  EMPTY = Slot(None, None) # 使用過被刪除
  def __init__(self):
    self._table = Array(8, init = HashTable.UNUSED) # 初始化,數組的每個元素都是UNUSED
    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) # abs函數返回絕對值 hash 是內置函數 _hash 直接使用內置的哈希函數,對數組的長度取模
  def _find_key(self, key):
    index = self._hash(key) # 先用 _hash方法計算出槽的位置
    _len = len(self._table) # 現保存下來長度
    while self._table[index] is not HashTable.UNUSED:  # 如果這個槽不是沒有被使用過
      if self._table[index] is HashTable.EMPTY: # 如果這個槽是,曾經有過值,不過被刪除了
        index = (index*5 +1 ) % _len    # cpython 使用的一種解決哈希沖突的方式
        continue
      elif self._table[index].key == key: # 正在使用, 如果key值相同
        return index
      else: # 這里就只剩最后一種可能, 正在使用,但是key沒有找到
        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.UNUSED)
  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 __contains__(self, key):   # 實現一個in操作符
    index = self._find_key(key)
    return index is not None
  def add(self, key, value):
    if key in self:  # 上面實現的in操作符
      index = self._find_key(key)
      self._table[index].value = value
      return False  # 返回False 表示沒有執行插入操作,執行的是更新操作
    else:
      index = self._find_slot_for_insert(key)
      self._table[index] = Slot(key, value) # 這兩部可能會調用_slot_can_insert 函數,不管是哪種情況,EMPTY 或 是 UNUSEZD,都將這個節點聲明為Slot類
      self.length += 1
      if self._load_factor >= 0.8:
        self._rehash()   # 當空間占用大于0.8 的時候,進行rehash 重新分配空間。
      return True
  def _rehash(self):
    old_table = self._table
    newsize = len(self._table) *2
    self._table = Array(newsize, HashTable.UNUSED)
    self.length = 0
    for slot in old_table:
      if slot is not HashTable.UNUSED and slot is not HashTable.EMPTY:  # 判斷這個slot 是有值的
        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 KeyError()
    value = self._table[index].value
    self.length -= 1
    self._table[index] = HashTable.EMPTY
    return value
  def __iter__(self):   # 遍歷操作,python 字典默認遍歷的是key,這里實現的也是遍歷key
    for slot in self._table:
      if slot not in(HashTable.EMPTY, HashTable.UNUSED):
        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 KeyError()
    else:
      return self.get(key)
  def _iter_slot(self):
    for slot in self._table:
      if slot not in (HashTable.EMPTY, HashTable.UNUSED):
        yield slot
  def items(self):
    for slot in self._iter_slot():
      yield (slot.key, slot.value)
  def keys(self):
    for slot in self._iter_slot():
      yield slot.key
  def values(self):
    for slot in self._iter_slot():
      yield slot.value
def test_dict():
  import random
  d = DictADT()
  d['a'] = 1   # 這時候調用 __setitem__ 方法
  assert d['a'] == 1
  d.remove('a')
  l = list(range(30))
  random.suffle(l)  # 打亂l
  for i in l:
    d.add(i, i )
  for i in range(30):
    assert d.get(i) == i
  assert sorted (list(d.keys())) == sorted(l)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

都匀市| 金乡县| 大洼县| 元氏县| 泗阳县| 汤原县| 桦川县| 尚志市| 鲁甸县| 海宁市| 金平| 婺源县| 宕昌县| 济阳县| 澄江县| 海安县| 若尔盖县| 讷河市| 霍邱县| 汕头市| 陕西省| 定兴县| 洪洞县| 利辛县| 崇明县| 六安市| 沛县| 江源县| 固安县| 海伦市| 苗栗县| 岐山县| 柳江县| 商河县| 英吉沙县| 伊吾县| 德庆县| 灯塔市| 靖远县| 简阳市| 大城县|