如何使用Python实现适配不同输入值形式的自定义索引
Python实现多取值匹配索引的实现方案
你要实现的根据不同输入取值返回对应结果的索引,本质是带匹配逻辑的映射结构,根据匹配复杂度可以选不同的实现方式:
1. 固定值精确匹配场景
如果所有输入都是离散的固定取值,直接用Python原生字典实现即可,查询时间复杂度O(1),性能最高:
# 构建索引 exact_match_index = { "product_1": "商品1:笔记本电脑", "product_2": "商品2:无线鼠标", 404: "错误码:页面不存在", ("admin", 1): "超级管理员账号" } # 查询方法 def query(input_val): return exact_match_index.get(input_val, "未找到对应匹配结果") # 测试 print(query("product_1")) # 输出:商品1:笔记本电脑
2. 支持规则/范围/模式匹配场景
如果需要支持数值范围、字符串格式、自定义条件这类非精确匹配(即参考示例里的多分支匹配索引效果),可以用优先级规则列表实现:按匹配优先级从高到低存储规则,查询时从前到后遍历,返回第一个命中规则的对应结果。
可直接复用的实现代码:
import re class MatcherIndex: def __init__(self): # 存储格式:(匹配校验函数, 对应返回结果),顺序即匹配优先级 self._rules = [] # 单独存精确匹配项,提升查询效率 self._exact_map = {} def add_exact(self, match_key, result): """添加精确匹配规则""" self._exact_map[match_key] = result def add_regex(self, pattern: str, result): """添加字符串正则匹配规则""" compiled_reg = re.compile(pattern) self._rules.append( (lambda x, reg=compiled_reg: isinstance(x, str) and bool(reg.fullmatch(x)), result) ) def add_num_range(self, result, min_val=None, max_val=None): """添加数值范围匹配规则""" def num_check(x): if not isinstance(x, (int, float)): return False if min_val is not None and x < min_val: return False if max_val is not None and x > max_val: return False return True self._rules.append((num_check, result)) def add_custom(self, check_func, result): """添加自定义匹配规则,支持任意判断逻辑""" self._rules.append((check_func, result)) def query(self, input_val): # 优先查精确匹配,性能最高 if input_val in self._exact_map: return self._exact_map[input_val] # 精确匹配未命中,按优先级遍历规则 for check, res in self._rules: if check(input_val): return res # 所有规则都没命中 return "无匹配结果" # 用法示例 if __name__ == "__main__": idx = MatcherIndex() # 按优先级添加规则 idx.add_exact(0, "匹配结果:输入为数值0") idx.add_num_range(min_val=1, max_val=100, result="匹配结果:输入为1-100区间的数值") idx.add_regex(r"^u_\d{3,}$", "匹配结果:输入为u_开头加3位以上数字的用户ID") idx.add_custom( check_func=lambda x: isinstance(x, list) and len(x) >= 3, result="匹配结果:输入为长度≥3的列表" ) # 测试查询 print(idx.query(0)) # 输出:匹配结果:输入为数值0 print(idx.query(66)) # 输出:匹配结果:输入为1-100区间的数值 print(idx.query("u_1234")) # 输出:匹配结果:输入为u_开头加3位以上数字的用户ID print(idx.query([1,2,3])) # 输出:匹配结果:输入为长度≥3的列表
优化建议
- 规则量级较大(千条以上)时,可以先给规则按输入类型打标签,查询时先判断输入类型,只遍历对应类型下的规则,减少无效遍历
- 如果需要返回所有命中的结果而非第一个优先级最高的,修改query方法,遍历所有规则收集命中结果再返回即可
- 涉及高频查询的规则可以提升优先级,放在规则列表靠前的位置,进一步降低平均查询耗时
内容的提问来源于stack exchange,提问作者Ander Alberro
相关产品推荐
相关产品推荐

