Python哈希表查询返回None问题排查求助
链地址哈希表查询全返回None?排查思路来啦
问题场景
从CSV文件加载数据插入链地址法哈希表(chainHashTable),插入后打印哈希表能确认Package对象已存入,但通过key查询时始终返回None,遍历所有key查询也无法获取Package的具体数据。
典型代码示例(模拟你的场景)
1. Package类实现
class Package: def __init__(self, pkg_id, addr, city): self.id = pkg_id self.address = addr self.city = city def __repr__(self): return f"Package({self.id}, {self.address}, {self.city})"
2. 链地址哈希表实现
class chainHashTable: def __init__(self, size=10): self.size = size self.buckets = [[] for _ in range(size)] def _get_hash(self, key): return hash(key) % self.size def add(self, key, value): idx = self._get_hash(key) # 检查重复key,存在则覆盖 for item in self.buckets[idx]: if item[0] == key: item[1] = value return self.buckets[idx].append([key, value]) def find(self, key): idx = self._get_hash(key) for item in self.buckets[idx]: if item[0] == key: return item[1] return None
3. CSV加载与测试代码
import csv def load_from_csv(path, hash_table): with open(path, 'r') as f: reader = csv.DictReader(f) for row in reader: pkg = Package(row['id'], row['address'], row['city']) # CSV读取的id默认是字符串类型 hash_table.add(row['id'], pkg) # 执行测试 ht = chainHashTable() load_from_csv('packages.csv', ht) print("哈希表内容:", ht.buckets) # 查询时使用整数类型的id print("查询id=1的包:", ht.find(1)) # 查询时使用字符串类型的id print("查询id='1'的包:", ht.find('1'))
当前输出
哈希表内容: [[], [['1', Package(1, 123 Elm St, Metro)]], [], [], [], [], [], [], [], []] 查询id=1的包: None 查询id='1'的包: Package(1, 123 Elm St, Metro)
期望输出
哈希表内容: [[], [['1', Package(1, 123 Elm St, Metro)]], [], [], [], [], [], [], [], []] 查询id=1的包: Package(1, 123 Elm St, Metro) 查询id='1'的包: Package(1, 123 Elm St, Metro)
排查与解决思路
1. 优先检查:Key类型不匹配(90%概率是此问题)
CSV读取的字段默认是字符串类型,若插入时使用字符串row['id']作为key,但查询时使用整数1,会导致两个问题:
- 哈希函数对不同类型的同一值计算出的索引可能不同
- 链表遍历匹配时
item[0] == key会判定为False(字符串'1'和整数1是完全不同的key)
解决方式:统一key类型
要么插入时转换为整数:
hash_table.add(int(row['id']), pkg)
要么查询时使用字符串:
ht.find('1')
2. 验证哈希函数的一致性
如果哈希函数对同一个key计算出不同的索引,插入和查询的位置就会错位。比如:
- key是自定义对象但未重写
__hash__方法,默认哈希值基于对象内存地址,每次新建对象哈希值不同 - 哈希函数中包含随机逻辑,导致插入和查询的索引不一致
验证方法:对同一key分别在插入前后计算哈希索引,确认结果一致:
key = '1' print("插入前哈希索引:", ht._get_hash(key)) ht.add(key, pkg) print("查询前哈希索引:", ht._get_hash(key))
3. 检查查询的匹配逻辑
若find方法中的匹配条件错误,也会导致查询失败。比如:
- 误将
item[1].id(Package对象的id属性)与key对比,而非插入时存储的item[0](原始key) - 匹配时写错索引,比如把
item[0]写成item[1]
4. 确认插入时的存储格式
如果插入时未正确存储[key, value]对,比如直接存入value而非[key, value],链表中仅存在Package对象,没有对应的key,查询时自然无法匹配,返回None。
总结
优先排查key类型是否统一,这是此类问题的高发原因;其次验证哈希函数的一致性;最后检查插入与查询的逻辑是否对应。
内容的提问来源于stack exchange,提问作者Chup91
相关产品推荐
相关产品推荐

