Python查找列表唯一元素报list index out of range错误如何修复
问题说明
给定数字列表,需查找并打印其中所有仅出现一次的元素,元素打印顺序需与原始列表中的出现顺序保持一致。原有实现采用先排序列表、再通过列表记录顺序的思路编写代码,运行时Python抛出list index out of range错误。
原有问题代码如下:
a = [int(s) for s in input().split()] a.sort() mylist = [] myorder = [] for i in range(len(a)): if a[i-1] != a[i] != a[i+1]: mylist.append(a[i]) myorder.append(a.index(a[i])) mylist = [mylist[k] for k in myorder] print(mylist)
错误根因
- 直接触发索引越界的原因:循环遍历范围是
0到len(a)-1,当i取到最后一个索引len(a)-1时,代码访问a[i+1]等价于访问a[len(a)],超出Python列表的合法索引范围(列表最大合法索引为长度减1)。另外当i=0时,a[i-1]会取到列表最后一个元素,会导致首尾元素的去重判断逻辑完全错误。 - 逻辑设计缺陷:调用
a.sort()会直接修改原列表,破坏原始元素顺序;后续通过a.index(a[i])获取元素位置时,遇到重复元素只会返回第一个匹配项的索引,根本无法还原原始顺序,即使修复越界问题,输出顺序也不符合要求。
推荐修复方案
不需要修改原始列表,直接统计元素出现频次,再按原始列表顺序筛选仅出现一次的元素即可,逻辑简单无边界问题,时间复杂度更优。
方案1:使用内置Counter统计频次
from collections import Counter # 读取输入,保留原始列表不做修改 origin = [int(s) for s in input().split()] count_dict = Counter(origin) # 按原始顺序收集仅出现一次的元素 res = [num for num in origin if count_dict[num] == 1] print(res)
方案2:手动实现频次统计(无需引入依赖)
origin = [int(s) for s in input().split()] count_dict = {} for num in origin: count_dict[num] = count_dict.get(num, 0) + 1 res = [num for num in origin if count_dict[num] == 1] print(res)
排序思路的修正写法(不推荐)
如果一定要保留排序判断的实现逻辑,需要先单独保存原始列表副本,遍历排序后列表时单独处理首尾边界,最后按原始列表顺序输出结果:
origin = [int(s) for s in input().split()] sorted_a = sorted(origin) unique_set = set() length = len(sorted_a) for i in range(length): if i == 0: # 处理首元素边界 if length == 1 or sorted_a[i] != sorted_a[i+1]: unique_set.add(sorted_a[i]) elif i == length - 1: # 处理尾元素边界 if sorted_a[i] != sorted_a[i-1]: unique_set.add(sorted_a[i]) else: # 处理中间元素 if sorted_a[i-1] != sorted_a[i] != sorted_a[i+1]: unique_set.add(sorted_a[i]) # 按原始顺序输出 res = [num for num in origin if num in unique_set] print(res)
该写法代码冗余度高,时间复杂度高于直接统计频次的方案,仅作为原思路的修正参考,日常使用优先选择统计频次的实现。
内容的提问来源于stack exchange,提问作者Meno
相关产品推荐
相关产品推荐

