如何在循环中根据条件更新列表前序元素并清理列表名称?
问题分析与解决方案
咱们先拆解下你代码里的几个核心问题,这也是导致前两个结果不符合预期的关键:
- 边界处理错误:当
i=0(第一个元素jellyfish)时,i-1等于-1,Python会取列表的最后一个元素smellyfish来做比较——这完全不是你想要的「前序元素」逻辑,所以第一个得分0.896是jellyfish和smellyfish的相似度,毫无意义。 - 没有真正修改列表:你写的
current=previous只是把临时变量current的值改了,并没有更新mylist里的实际元素,后续比较还是在用原列表的旧值,等于白做替换。 - 逻辑顺序问题:你应该基于已经清理过的前一个元素来比较当前元素,而不是原列表的原始值,否则替换操作的效果无法传递下去。
修正后的代码实现
这里提供两种实用思路,推荐第一种,避免修改原始数据:
方案1:维护独立的结果列表(推荐)
这种方式不改动原始列表,逐步构建清理后的结果,逻辑更清晰:
import jellyfish as jf mylist = ['jellyfish','jellyish','jellyish','smellyfish'] # Python2需要转unicode,Python3直接用str即可,可注释掉下面这行 # mylist = [unicode(i) for i in mylist] cleaned_list = [] for idx, name in enumerate(mylist): if idx == 0: # 第一个元素直接加入结果,没有前序元素可比较 cleaned_list.append(name) continue # 和结果列表的最后一个元素(已经清理过的前序元素)做比较 prev_name = cleaned_list[-1] score = jf.jaro_winkler(name, prev_name) if score > 0.96: # 相似度达标,用前序元素替换当前元素 cleaned_list.append(prev_name) else: cleaned_list.append(name) print(f"{cleaned_list[-1]} {score}") print("\n清理后的最终列表:", cleaned_list)
方案2:直接修改原列表
如果一定要修改原始列表,需要确保每次比较的是更新后的前序元素:
import jellyfish as jf mylist = ['jellyfish','jellyish','jellyish','smellyfish'] # mylist = [unicode(i) for i in mylist] # Python2适配 # 从第二个元素开始循环,跳过无前置的第一个元素 for idx in range(1, len(mylist)): current = mylist[idx] previous = mylist[idx-1] score = jf.jaro_winkler(current, previous) if score > 0.96: # 直接修改列表中的当前元素 mylist[idx] = previous print(f"{mylist[idx]} {score}") print("\n清理后的最终列表:", mylist)
运行结果验证
两种方案的输出都会符合预期:
jellyfish 0.977777777778 jellyfish 1.0 smellyfish 0.858333333333 清理后的最终列表: ['jellyfish', 'jellyfish', 'jellyfish', 'smellyfish']
这样就实现了你想要的效果:把连续的高相似度名称统一为前序的标准名称。
内容的提问来源于stack exchange,提问作者newtoCS
相关产品推荐
相关产品推荐

