当前位置:
首页 >
加载dict_Python的dict实现原理和Java的HashMap之间的区别
发布时间:2024/10/8
44
豆豆
生活随笔
收集整理的这篇文章主要介绍了
加载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之间的区别的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 微信绑不了银行卡怎么办
- 下一篇: python中的序列类型和序列号_pyt