Python中使用pop()方法时List index out of range错误原因探究
正向迭代删列表元素报索引越界,反向迭代却不报错的原因
当执行下面这段代码时,会触发List index out of range错误:
class Solution: def removeDuplicates(self, nums: List[int]) -> int: for i in range(1, len(nums)): if nums[i] == nums[i-1]: nums.pop(i) return len(nums)
但改用reversed()反向迭代索引后,同样在迭代时删除元素,却不会报错:
class Solution: def removeDuplicates(self, nums: List[int]) -> int: for i in reversed(range(1, len(nums))): if nums[i] == nums[i-1]: nums.pop(i) return len(nums)
正向迭代报错的根本原因
range(1, len(nums))是一次性生成所有迭代用的索引的。比如初始列表长度为5,会直接生成[1,2,3,4]这组索引。但删除元素会让列表长度缩短,后续元素会往前移位:
- 举个具体例子:假设初始nums是
[1,1,2,2,3],第一次循环i=1,执行pop(1)后nums变成[1,2,2,3],长度变为4。 - 但循环还是会按原索引序列继续走,当i走到3时,此时nums的最大索引是2,访问nums[3]自然就触发索引越界错误。
简单说:正向迭代时,后续要访问的索引是提前固定的,但列表长度在缩短,导致后面的索引超出了当前列表的有效范围。
反向迭代为什么不会报错?
reversed(range(1, len(nums)))会先基于初始列表长度生成正向索引序列,再反转成从大到小的顺序(比如初始长度5的话,就是[4,3,2,1])。关键在于从后往前删元素的逻辑:
- 删除靠后的元素时,不会影响前面还没迭代到的索引位置——因为前面的元素不会因为后面的删除操作往前移位。
- 还是用刚才的例子:nums初始是
[1,1,2,2,3],反向迭代先处理i=4,没问题;接着i=3,pop(3)后nums变成[1,1,2,3],此时要处理的下一个索引是2,这个索引在当前列表里是有效的;最后处理i=1,也不会有问题。
全程所有要访问的索引,在当前列表中都是存在的,自然不会触发越界错误。
内容的提问来源于stack exchange,提问作者childoflogos
相关产品推荐
相关产品推荐

