Python dict-字典

Python dict-字典

映射(mapping)结构,基于哈希表存储键值对数据

key必须是可哈希类型

哈希冲突时,采用开放寻址法

散列表是一个稀疏数组。1/3表元为空,因此空间效率低

散列表里元素通常叫做表元(bucket)

散列值

获取散列值

内置类型 hash()

自定义类型,重写__hash__。

两个对象相等,那么散列值必须相等。

自定义类型,重写__eq__

散列值保证索引空间中分散:

理想情况下,越相似,它们的散列值差别越是大

散列表算法

获得my_dict[search_key]

1)调用hash(search_key)来计算search_key的散列值

2)把这个值最低的几位数字当做偏移量,在散列表中查找表元(几位,根据散列表大小)

3)若找到表元为空,则KeyError

4)若表元不为空,表元里面有一对found_key:found_value

5)如果search_key = found_key 为True,返回found_value

​ 如果为False,称为散列冲突

Python dict-字典_第1张图片

操作时间复杂度:

操作 时间复杂度
copy O(n)
get(value) O(1)
set(value) O(1)
delete(value) O(1)
search(in) O(1)
iterration O(n)

dict的实现及其导致的结果

键必须可散列的

一个可散列的对象必须满足以下要求:

(1) 支持 hash() 函数,并且通过 hash() 方法所得到的散列 值是不变的。

(2) 支持通过 eq() 方法来检测相等性。 (3) 若 a == b 为真,则 hash(a) == hash(b) 也为真。

所有由用户自定义的对象默认都是可散列的,因为它们的散列值由 id() 来获取,而且它们都是不相等的。

​ 自定义类型默认实现了__hash__和__eq__

字典在内存上的开销巨大

散列表必须稀疏,导致空间的效率低。优化往往和可维护性的对立面

键查询很快

dict的实现是典型的空间换时间:

字典类型有这巨大的内存开销,但它们提供了无视数据量大小的快速访问

键的次序取决于添加顺序

当往dict里添加新建而又发生了散列冲突的时候,新建可能被安排存放在另外一个位置。

两个内容相等,顺序不同的,题目是相等

添加:

collections.OrderDict,有序字典

往字典里添加新建可能会改变已有键的顺序

无论何时往字典里添加新的键,Python解释器都可能做出字典扩容的决定。

扩容过程中可能会发生新的冲突,导致新散列表中的键的次序发生变化。

由此可见:不要对字典同时进行迭代和修改。

想扫描并修改一个字典,最好分为2步:

1:对字典迭代,以得到需要添加的内容,把这些内容放在一个新字典里;

2:迭代结束之后再对原有字典进行更新

注意:

在 Python 3 :

.keys()、.items() 和 .values() 方 法返回的都是字典视图。

也就是说,这些方法返回的值更像集 合。

视图还有动态的特性, 它们可以实时反馈字典的变化

你可能感兴趣的:(Python)