使用Python re.findall匹配CSV关键词时遇unhashable type: 'dict'错误求助
问题分析
报错TypeError: unhashable type: 'dict'的核心原因是你传给re.findall的self.ktxt是字典类型,但re.findall要求第一个参数必须是字符串或正则表达式对象。结合你提到的read_key方法问题,大概率是读取CSV时用了DictReader之类的方式,把每行关键词包装成了字典(比如{'列名': '关键词内容'})。
修正方案
以下是针对read_key和find方法的完整修正代码,同时优化了关键词匹配的效率和准确性:
1. 修正关键词读取方法
把CSV中的关键词读取为字符串列表,并编译成正则模式(处理关键词中的正则特殊字符):
import re import csv class KeywordSearcher: def __init__(self): self.keywords = [] self.match_pattern = None def read_key(self, csv_path): # 读取单列CSV,每行一个关键词 with open(csv_path, 'r', encoding='utf-8') as f: # 用csv.reader而非DictReader,避免生成字典 csv_reader = csv.reader(f) # 过滤空行,取出每行第一个元素并去除首尾空格 self.keywords = [row[0].strip() for row in csv_reader if row] # 编译正则模式:用|分隔关键词,re.escape处理特殊字符(如. *等) escaped_terms = [re.escape(kw) for kw in self.keywords] self.match_pattern = re.compile('|'.join(escaped_terms))
2. 修正文件搜索与统计方法
利用编译好的正则模式批量匹配,再统计每个关键词的出现次数:
def find(self, target_file): with open(target_file, 'r', encoding='utf-8') as f: file_content = f.read() # 一次性获取所有匹配的关键词 all_matches = self.match_pattern.findall(file_content) # 统计每个关键词的出现次数 count_result = {} for kw in self.keywords: count_result[kw] = all_matches.count(kw) return { "文件名": target_file, "关键词出现次数": count_result }
3. 调用示例
# 初始化搜索器 searcher = KeywordSearcher() # 读取关键词文件 searcher.read_key('keyterms.csv') # 搜索目标文件 result = searcher.find('目标文件夹/示例文本.txt') print(result)
关键细节说明
- 避免字典生成:用
csv.reader替代csv.DictReader,直接获取字符串形式的关键词,从根源解决unhashable type: 'dict'错误。 - 正则转义:通过
re.escape处理关键词中的特殊字符(比如关键词包含.时,不会被正则当成通配符),保证匹配准确性。 - 高效统计:一次性获取所有匹配结果再统计,比逐个关键词调用
re.findall减少IO和正则匹配次数,提升效率。
内容的提问来源于stack exchange,提问作者3xogenic
相关产品推荐
相关产品推荐

