字符串匹配生成字典时触发TypeError: 'NoneType'对象不可下标访问
解决TypeError: 'NoneType' object is not subscriptable问题
你遇到的这个错误完全符合你的推测——当score_cutoff设置过高时,部分测试文本找不到符合阈值的匹配结果,导致后续处理中出现了None值,而你尝试对None做下标访问(y[0])就触发了这个错误。
错误原因分析
当process.extractBests()找不到符合score_cutoff的匹配项时,会返回空列表。当你把这些空列表存入aggregated_matches这个DataFrame时,对应行的Match1、Match2等列会被填充为None(因为空列表没有足够的元素来填充这些列)。之后在循环里执行[y[0] for y in aggregated_matches["Match" + str(x)]]时,一旦遇到y是None,尝试取y[0]就会直接抛出TypeError。而当你把阈值降到20时,几乎所有文本都能找到匹配,自然不会出现None的情况,错误也就消失了。
解决方案
我们可以从源头保证数据结构的一致性,让每个匹配结果列表的长度都等于num_match,不足的部分用占位符填充。这样存入DataFrame后就不会出现None值,后续的下标访问也能正常进行。
修改后的完整代码如下:
def StringMatch(master, testfile, num_match=3, score_cutoff=95, limit=3): master_names = master.iloc[:,3] test_names = testfile.iloc[:,0] # 处理每个测试名称的匹配结果,确保每个列表长度固定为num_match fhp_new = [] for x in test_names: matches = process.extractBests(x, master_names, score_cutoff=score_cutoff, limit=limit) # 如果匹配结果不足,用占位符填充(这里用("", 0),你可以根据需求改成其他值,比如(None, 0)) matches += [("", 0)] * (num_match - len(matches)) fhp_new.append(matches) # 更简洁的列名生成方式 columns = [f"Match{i}" for i in range(1, num_match+1)] aggregated_matches = pd.DataFrame(fhp_new, columns=columns) d = {} for x in range(1, num_match + 1): # 现在每个y都是元组,不会出现None,安全访问y[0] d[f"Match{x}"] = [y[0] for y in aggregated_matches[f"Match{x}"]] print(d)
备选方案(快速修复)
如果你不想修改生成fhp_new的逻辑,也可以直接在列表推导式中增加对None的判断,给无匹配的情况设置默认值:
d[f"Match{x}"] = [y[0] if y is not None else "" for y in aggregated_matches[f"Match{x}"]]
不过这种方法属于“事后补救”,不如第一种方法从源头保证数据一致性来得稳妥。
内容的提问来源于stack exchange,提问作者isic5
相关产品推荐
相关产品推荐

