Try...except异常处理+选择排序测试时索引越界问题排查求助
问题分析与解决方案
1. 索引越界的直接原因:verifyList函数逻辑错误
你的verifyList在检查列表是否升序时,循环范围写的是range(len(L))——当循环到最后一个元素(elm = len(L)-1)时,L[elm+1]会访问超出列表索引的位置(列表最大索引是len(L)-1),这就是触发索引越界错误的根源。
修复后的verifyList:
def verifyList(L: list) -> bool: # 只遍历到倒数第二个元素,避免访问不存在的索引 for elm in range(len(L) - 1): if L[elm] > L[elm + 1]: return False return True
2. tri_selection函数的排序逻辑错误
当前的实现根本不是选择排序:它会把列表排成降序,还会直接修改传入的原列表,容易导致测试时的状态混乱。正确的选择排序应该是每次找到未排序部分的最小值,放到已排序部分的末尾,而且最好不修改原列表。
修复后的升序选择排序:
def tri_selection(L: list) -> list: """选择排序:返回升序排列的新列表,不修改原列表""" assert isinstance(L, list), "输入必须是列表" # 复制原列表,避免破坏输入的原始数据 lst = L.copy() n = len(lst) for i in range(n): # 找到未排序区间的最小元素索引 min_idx = i for j in range(i + 1, n): if lst[j] < lst[min_idx]: min_idx = j # 交换当前位置和最小元素的位置 lst[i], lst[min_idx] = lst[min_idx], lst[i] return lst
3. __test__函数的重复调用问题
在__test__的else块里,你又调用了一次function(L)——如果函数是原地修改列表的实现,此时原列表已经被之前的调用修改,会导致重复操作。应该提前保存排序结果,避免重复调用函数。
修复后的__test__:
def __test__(L: list) -> None: assert isinstance(L, list), "输入必须是列表" functionsToTry = [tri_selection] for function in functionsToTry: try: # 保存排序结果,避免重复调用函数 sorted_list = function(L) if verifyList(sorted_list): print(f'[✓] {function.__name__} : 运行成功') else: print(f'[≃] {function.__name__} : 排序结果不符合升序要求') except Exception as error: print(f'[✕] {function.__name__} : {str(error)}') else: print(f'排序结果:{sorted_list}') __test__([3, 2, 1])
额外小提示
- 类型检查用
isinstance(L, list)代替type(L) == list,前者支持继承,更符合Python的类型规范。 - 打印信息用f-string,比字符串拼接更简洁好读。
内容的提问来源于stack exchange,提问作者user19878266
相关产品推荐
相关产品推荐

