使用fuzz.ratio()实现两列表字符串匹配的函数问题排查
问题分析与修复方案
你的函数出现问题主要是两个核心逻辑错误,咱们一步步拆解:
错误原因
1. 元素被重复添加
在你的双层循环里,每一次item1和item2的比较都会触发一次判断——只要得分<60就把item1塞进no_matching,得分>60就塞进matching。拿Real Madrid举例:它和Barcelona、Milan的得分都低于60,会被两次加入no_matching;和Madrid得分高于60,又会被加入matching。最终你的结果列表里会充满重复元素,完全不符合预期。
2. 匹配逻辑颠倒
你需要的是「只要item1和list2中至少一个元素匹配得分>60,就归为matching;否则归为no_matching」,但你的代码逻辑变成了「只要有一次匹配得分<60就进no_matching,只要有一次>60就进matching」——这会导致同一个元素同时出现在两个列表里,逻辑完全混乱。
修复后的代码
我们需要先为每个item1做「是否存在符合条件的匹配」的整体判断,而不是每次比较都直接添加元素:
from fuzzywuzzy import fuzz def Matching(list1, list2): matching = [] no_matching = [] for item1 in list1: # 标记当前元素是否找到符合要求的匹配 has_valid_match = False for item2 in list2: score = fuzz.ratio(item1, item2) if score > 60: has_valid_match = True break # 找到一个符合条件的就不用继续比较了,提升效率 # 循环结束后统一判断归属 if has_valid_match: matching.append(item1) else: no_matching.append(item1) return matching, no_matching
测试验证
用你给出的例子测试:
list1 = ["Real Madrid", "Benfica", "Lazio", "FC Milan"] list2 = ["Madrid", "Barcelona", "Milan"] matching_list, no_matching_list = Matching(list1, list2) print("matching:", matching_list) # 输出: ['Real Madrid', 'FC Milan'] print("no_matching:", no_matching_list) # 输出: ['Benfica', 'Lazio']
完全符合你的预期结果。
额外优化点
- 加入
break语句:一旦找到符合条件的item2就停止内层循环,避免不必要的计算,尤其是当列表元素很多时,能显著提升效率。 - 变量命名更清晰:把
found_match改成has_valid_match,让代码可读性更强。
内容的提问来源于stack exchange,提问作者feration48
相关产品推荐
相关产品推荐

