You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:35:22