字典是根据键的哈希值来存储和查找值的,在字典(也称为哈希表或映射)这种数据结构中,每个键值对(key-value pair)的存储和查找操作都是基于键(key)的哈希值来进行的。哈希值是一个数字,它是通过应用一个哈希函数到键上得到的。这个哈希值决定了键值对在字典内部数组或链表中的位置。这种方法使得字典能够在平均情况下实现非常快速的查找、插入和删除操作,时间复杂度接近O(1)。
例子
假设我们有一个简单的字典,用来存储学生的名字和他们的年龄:
# 使用不可变类型作为键,任意类型作为值
my_dict = {
'name': 'Alice', # 字符串键,字符串值
'age': 30, # 字符串键,整数值
'is_student': False, # 字符串键,布尔值
'courses': ('Math', 'Science'), # 字符串键,元组值
'grades': { # 字符串键,字典值
'Math': 'A',
'Science': 'B'
},
'function': lambda x: x * 2 # 字符串键,函数值
}
# 尝试使用可变类型作为键(这将引发TypeError)
# wrong_dict = {[1, 2, 3]: 'This will not work'} # 列表是不可变的,不能用作键
-
哈希函数:当我们想要在这个字典中存储或查找一个键值对时,Python首先会对键(比如"Alice")应用一个哈希函数。这个哈希函数会将键转换成一个整数哈希值。例如,假设哈希函数将"Alice"转换为哈希值12345。
-
存储位置:然后,这个哈希值会被用来确定键值对在字典内部存储数组中的索引位置。为了简化,我们可以假设字典使用一个长度为10000的数组作为存储桶(bucket)。那么,键值对("Alice", 20)就会被存储在数组的第12345 % 10000 = 2345个位置上。
-
查找过程:当我们想要查找"Alice"的年龄时,Python会再次对"Alice"应用相同的哈希函数,得到哈希值12345,然后计算出索引位置2345,并直接访问该位置来获取值20。
-
处理冲突:需要注意的是,不同的键可能会产生相同的哈希值(这称为哈希冲突)。为了处理这种情况,字典通常会在每个存储桶位置使用一个链表或其他数据结构来存储多个键值对。当发生哈希冲突时,字典会遍历这个链表来找到正确的键值对。
关键点
- 哈希函数:将键转换为哈希值。
- 存储桶:内部数组或其他数据结构,用于存储键值对。
- 冲突处理:使用链表或其他方法来处理哈希冲突。
这种基于哈希值的存储和查找机制使得字典成为一种非常高效的数据结构,适用于需要快速访问、插入和删除操作的应用场景。