
本文详解归并排序实现中因误用空列表赋值导致的 IndexError: list assignment index out of range 问题,并提供可运行的修正方案,涵盖辅助列表初始化、结果回写机制及完整调用流程。
本文详解归并排序实现中因误用空列表赋值导致的 `indexerror: list assignment index out of range` 问题,并提供可运行的修正方案,涵盖辅助列表初始化、结果回写机制及完整调用流程。
归并排序是一种经典的分治(Divide and Conquer)排序算法,其核心在于将数组递归二分、分别排序后合并。然而,在 Python 中实现时,一个常见且隐蔽的错误是:在 merge 函数中直接对空列表 b = [] 执行索引赋值(如 b[k] = ...)。由于空列表没有预分配内存空间,任何形如 b[0] = x 的操作都会触发 IndexError —— 这正是原代码崩溃的根本原因。
要解决该问题,关键在于正确管理临时存储结构。推荐做法是改用 list.append() 动态扩展辅助列表,而非依赖预定义长度的索引访问。同时,必须确保排序结果能正确回写到原数组中,否则递归过程产生的有序片段将被丢弃。
以下是修正后的完整实现(含注释说明):
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
def merge(a, lower, middle, upper, b):
i = lower
j = middle + 1
# 移除 k 变量:不再通过索引赋值,改用 append()
while i <= middle and j <= upper:
if a[i] <= a[j]:
b.append(a[i])
i += 1
else:
b.append(a[j])
j += 1
# 处理剩余元素(左半段或右半段)
while i <= middle:
b.append(a[i])
i += 1
while j <= upper:
b.append(a[j])
j += 1
return b
def mergesort(a, lower, upper):
if lower < upper:
middle = (lower + upper) // 2
mergesort(a, lower, middle)
mergesort(a, middle + 1, upper)
# 关键修正:用切片赋值将合并结果写回原数组对应区间
temp = [] # 每次 merge 创建新空列表
merged = merge(a, lower, middle, upper, temp)
a[lower : upper + 1] = merged # 回写,保证原数组被修改
# 使用示例
arr = [1, 3, 2, 7, 11, 10]
mergesort(arr, 0, len(arr) - 1)
print(arr) # 输出: [1, 2, 3, 7, 10, 11]⚠️ 注意事项与最佳实践:
立即学习“Python免费学习笔记(深入)”;
-
不要复用全局或外部列表作为
b:每次merge应创建独立的空列表(如temp = []),避免跨层污染; -
务必执行结果回写:
a[lower:upper+1] = merged是就地排序的关键,缺失此步将导致函数“无副作用”; -
边界检查需严谨:
upper必须为有效索引(即),主调用应使用 <code>len(a)-1而非硬编码数值; - 若需返回新列表而非就地修改,可将
mergesort改为返回副本,但当前设计更符合典型归并排序的空间优化逻辑。
该实现时间复杂度稳定为 $O(n \log n)$,空间复杂度为 $O(n)$(用于临时合并数组),完全规避了索引越界风险,并具备良好的可读性与工程可用性。

















