加载dict_Python的dict实现原理和Java的HashMap之间的区别
生活随笔
收集整理的這篇文章主要介紹了
加载dict_Python的dict实现原理和Java的HashMap之间的区别
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Python內部很地方都使用著dict這種結構,在對象屬性__dict__就是一個字典,所以對其效率要求很高。
dict采用了哈希表,最低能在 O(1)時間內完成搜索。同樣的java的HashMap也是采用了哈希表實現,不同是dict在發生哈希沖突的時候采用了開放尋址法,而HashMap采用了鏈接法。
開放尋址法
優點
缺點
下面是我根據自己的理解去用python實現的字典,簡化了很的功能,比如對象緩沖池、String哈希的優化等等,如果有錯誤的或者更好的實現方式請指出。因為python沒有純粹的數組結構,所以數組也是借用list實現的. #python3.6 from collections import namedtupleclass SimpleArray(object):#簡單的數組類實現def __init__(self, mix):self.container = [None for i in range(mix)]def __len__(self):return len(self.container)def __setitem__(self, key, value):return self.container.__setitem__(key,value)def __getitem__(self, item):return self.container.__getitem__(item)def __delitem__(self, key):return self.container.__setitem__(key, None)def __str__(self):return str(self.container)class SimpleDict(object):#簡單的字典類實現Init_length = 8 # 初始化的大小Load_factor = 2/3 # 擴容因子def __init__(self):self._array_len = SimpleDict.Init_lengthself._array = SimpleArray(self._array_len)self._used = 0self.dictObj = namedtuple("dictObj","key value") # 這里其實可以用數組也可以的,namedtuple是為了讓代碼更可讀def __getitem__(self, item):key = self._hash(item)dictObj = self._array[key]if dictObj is not None and dictObj.key == item:return dictObj.valueelse:for new_key in self._second_hash(key):if self._array[new_key] is not None and item == self._array[new_key].key:return self._array[new_key].valuedef __setitem__(self, key, value):# 計算是否需要擴容if (self._used / self._array_len) > SimpleDict.Load_factor:self._new_array()#根據鍵的hash值來計算得出位置索引hash_key = self._hash(key)new_key = self._second_hash(hash_key)while True:if self._array[hash_key] is None or key == self._array[hash_key].key:break# 發生哈希碰撞根據二次探查函數得出下一個索引的位置hash_key = next(new_key)if abs(hash_key) >= self._array_len:self._new_array()hash_key = self._hash(key)# 找到空位將鍵值對象放入self._array[hash_key] = self.dictObj(key, value)self._used += 1def __delitem__(self, key):hash_key = self._hash(key)if key != self._array[hash_key].key:for new_key in self._second_hash(hash_key):if key == self._array[new_key].key:hash_key = new_keyself._array[hash_key] = Noneself._used -= 1def _hash(self, key):# 計算哈希值return hash(key) & (self._array_len-1)def _second_hash(self, hash_key):# 簡單的二次探查函數實現count = 1for i in range(self._array_len):new_key = hash_key + count**2if abs(new_key) < self._array_len:yield new_keynew_key = hash_key - count**2if abs(new_key) < self._array_len:yield new_keycount += 1def _new_array(self):# 擴容old_array = self._arrayself._array_len = self._array_len * 2 # 擴容2倍大小self._array = SimpleArray(self._array_len)for i in range(len(old_array)):dictObj = old_array[i]if dictObj is not None:self[dictObj.key] = dictObj.valuedef __str__(self):result = ", ".join("%s:%s"%(obj.key, obj.value)for obj in self._arrayif obj is not None)return "{" + result + "}"if __name__ == '__main__':d = SimpleDict()for i in range(20):d[str(i)] = iprint(d)print(d["10"])del d["11"]print(d)
鏈接法
優點
缺點
其中有很重要的兩個參數影響其性能: 初始容量和加載因子
dict:默認初始容量為8,加載因子為2/3
HashMap: 默認初始容量為16, 加載因子為0.75
兩者相同的是擴容的長度必需是2的N次方
總結
以上是生活随笔為你收集整理的加载dict_Python的dict实现原理和Java的HashMap之间的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信绑不了银行卡怎么办
- 下一篇: 一码通是什么意思?