本文目录导读:

- 案例1:基础增删改查(像操作通讯录)
- 案例2:统计频率(最经典的应用)
- 案例3:用哈希表“去重”+“快速查找”
- 案例4:两数之和(面试高频题)
- 案例5:用哈希表做“缓存”或“记忆化”
- 案例6:处理更复杂的数据(哈希表嵌套)
- 总结:什么时候该用哈希表?
在Python中,哈希表最常见的实现就是字典(dict),你可以把它想象成一个“超级通讯录”——通过名字(键)直接找到电话号码(值),而不是一页页翻。
下面是几个从简单到实用的案例,看看哈希表在Python中怎么用。
案例1:基础增删改查(像操作通讯录)
这是最直接的用法,哈希表(字典)支持O(1)的平均时间复杂度操作。
# 创建一个哈希表(字典)
phone_book = {
"Alice": "123-456",
"Bob": "789-012"
}
# 1. 添加/更新(键不存在则添加,存在则更新)
phone_book["Charlie"] = "345-678"
phone_book["Alice"] = "999-999" # 更新Alice的号码
# 2. 查找(用in判断,直接访问)
if "Bob" in phone_book:
print(f"Bob的电话是: {phone_book['Bob']}")
# 3. 删除
del phone_book["Charlie"]
# 4. 遍历
for name, number in phone_book.items():
print(f"{name}: {number}")
为什么用哈希表?
- 查“Alice”的电话,不用遍历整个列表,直接定位——这就是哈希表的核心优势。
案例2:统计频率(最经典的应用)
哈希表用来“数东西”特别好用。
# 场景:统计一段文字中每个字符出现的次数
text = "hello world"
char_count = {} # 空哈希表
for char in text:
if char in char_count:
char_count[char] += 1
else:
char_count[char] = 1
print(char_count)
# 输出:{'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}
更Pythonic的写法(用get方法):
char_count = {}
for char in text:
char_count[char] = char_count.get(char, 0) + 1
再进阶:用collections.Counter(专业工具)
from collections import Counter char_count = Counter(text) # 一行搞定 print(char_count.most_common(2)) # 出现最多的前2个字符
案例3:用哈希表“去重”+“快速查找”
哈希表的键是唯一的,天然适合去重;同时查找速度极快。
# 场景:在数组中找出第一个重复出现的数字
def find_first_duplicate(nums):
seen = {} # 哈希表:记录数字第一次出现的位置
for i, num in enumerate(nums):
if num in seen:
return num # 找到了重复
seen[num] = i
return None
print(find_first_duplicate([2, 1, 3, 5, 3, 2]))
# 输出:3(第一个重复的是3,不是2)
案例4:两数之和(面试高频题)
这道题特别能体现哈希表“空间换时间”的思想。
# 问题:给定数组 [2, 7, 11, 15] 和目标值 9,找出和为9的两个数的索引
def two_sum(nums, target):
num_map = {} # 哈希表:{数字: 索引}
for i, num in enumerate(nums):
complement = target - num # 需要的另一个数
if complement in num_map:
# 找到了!返回两个索引
return [num_map[complement], i]
num_map[num] = i # 把当前数存入哈希表
return []
result = two_sum([2, 7, 11, 15], 9)
print(result) # 输出:[0, 1](因为2+7=9)
不哈希表的做法:双重循环O(n²)。
哈希表做法:一次遍历O(n)。
案例5:用哈希表做“缓存”或“记忆化”
比如斐波那契数列,用哈希表存已经算过的结果,避免重复计算(就是动态规划里的“备忘录”)。
memo = {} # 哈希表作缓存
def fib(n):
if n <= 1:
return n
if n not in memo: # 没算过才去算
memo[n] = fib(n-1) + fib(n-2)
return memo[n]
print(fib(50)) # 秒出结果,不缓存会卡死
案例6:处理更复杂的数据(哈希表嵌套)
哈希表的值可以是任何东西,包括另一个哈希表或列表。
# 场景:管理一个班级的学生成绩
grades = {
"张三": {"数学": 95, "语文": 88},
"李四": {"数学": 78, "语文": 92}
}
# 查询张三的数学成绩
print(grades["张三"]["数学"]) # 95
# 添加李四的英语成绩
grades["李四"]["英语"] = 85
# 遍历
for student, subjects in grades.items():
print(f"{student}: {subjects}")
什么时候该用哈希表?
| 场景 | 为什么用 |
|---|---|
| 查找元素 | O(1)时间,比列表O(n)快很多 |
| 统计频率 | 键值对天然适合计数 |
| 去重 | 键必须唯一 |
| 缓存/记忆化 | 避免重复计算 |
| 建立映射关系 | 用户名→用户信息” |
记住一句话:只要你想“通过一个东西快速找到另一个东西”,就用哈希表(字典)。
最后提醒一点:字典的键必须是“可哈希的”——简单说,就是不可变类型(字符串、数字、元组),列表、字典本身不能作为键。