Python正则匹配预定义列表清洗字符串触发unhashable type:list报错求解
报错原因定位
核心报错原因
- 命名冲突:直接把自定义货币列表命名为
list,覆盖Python内置的list类型,容易引发作用域内的类型匹配错误 - 正则API调用不规范:
re.findall()要求传入两个必填参数:匹配正则、待检索目标字符串,但代码里只传了拼好的正则片段,没有传入要处理的string参数,调用本身不符合API规范re.findall()返回值是匹配结果组成的列表,代码直接把这个列表作为第一个参数传给re.sub(),正则方法要求第一个入参必须是字符串形式的正则表达式或编译后的正则对象,传入这类不可哈希的可变列表类型时,内部缓存逻辑会触发TypeError: unhashable type: 'list'
- 逻辑冗余可读性差:
- 写了两次重复的字符串替换逻辑,第一次替换的入参本身不合法,第二次单独替换
\sTest\b的操作属于冗余设计 - 函数内部定义了和函数同名的局部变量
clean_it,虽然不会直接触发报错,但会大幅降低代码可读性,容易引发逻辑错误
- 写了两次重复的字符串替换逻辑,第一次替换的入参本身不合法,第二次单独替换
正确实现方案
正则实现版本(最小化改动适配原有编码习惯)
- 替换自定义列表的命名,避免和内置类型冲突
- 预编译正则表达式,避免每次调用函数都重复编译,适配数百条数据的处理效率要求
- 一次性匹配「前置内容之后的 空格+货币+空格+Test」整段内容,替换为空后去除前后空白即可得到目标结果
- 对货币匹配内容做正则转义,避免后续列表新增特殊字符时触发匹配异常
import re # 语义化命名自定义列表,避免覆盖内置类型 CURRENCY_LIST = ['EUR', 'USD', 'GBP'] # 预编译正则:匹配 空格 + 任意货币值 + 空格 + Test 单词边界,非捕获组优化匹配效率 MATCH_PATTERN = re.compile( r'\s+(?:' + '|'.join(re.escape(curr) for curr in CURRENCY_LIST) + r')\s+Test\b' ) def clean_it(string): # 保留原有的非ASCII字符清洗逻辑 cleaned_str = string.encode("ascii", errors="ignore").decode() # 一次性替换匹配到的货币+Test片段 cleaned_str = MATCH_PATTERN.sub('', cleaned_str) # 去除前后残留空白 return cleaned_str.strip() # 测试验证 ref = [ ' asdf EUR Test', ' jkl USD Test', ' qwert GBP Test' ] processed_result = [clean_it(s) for s in ref] # 输出结果:['asdf', 'jkl', 'qwert']
轻量化非正则实现(适配固定结构场景)
如果待处理字符串结构高度固定(前置有效内容 + 空格 + 货币 + 空格 + Test),可以不用正则直接拆分,处理开销更低:
CURRENCY_LIST = ['EUR', 'USD', 'GBP'] def clean_it_simple(string): cleaned_str = string.encode("ascii", errors="ignore").decode() # 定位对应货币位置,取前置内容清洗 for curr in CURRENCY_LIST: if curr in cleaned_str: return cleaned_str.split(curr)[0].strip() # 无匹配货币时返回清洗后的原字符串 return cleaned_str.strip()
内容的提问来源于stack exchange,提问作者brko
相关产品推荐
相关产品推荐

