Python数组遍历为何需用len(nums)-2缩短范围?CodingBat中索引越界报错问题解析
嘿,我来帮你理清楚这个困惑——你遇到的绝对不是CodingBat编译器的问题,而是代码里隐藏的索引越界风险,只是本地测试时刚好没触发而已!咱们一步步拆解:
为什么官方解法要用range(len(nums)-2)?
咱们要找的是连续的1、2、3,也就是需要同时访问nums[i]、nums[i+1]、nums[i+2]三个元素。列表的索引是从0开始的,假设数组长度是n,最大的有效索引是n-1。
为了让i+2不超过最大索引,i的最大值必须是n-3(因为(n-3)+2 = n-1,刚好是最后一个元素的索引)。而range(len(nums)-2)生成的序列是0,1,...,len(nums)-3,完美覆盖了所有合法的i值,不会出现索引越界的情况。
为什么本地运行for i in range(len(nums)):好像没问题?
那是因为你本地测试的数组,大概率在循环还没走到会触发越界的i值时,就已经找到1、2、3的序列并提前return True了!比如你测试[1,2,3,4],当i=0时就满足条件直接返回,根本不会执行到i=2或i=3的循环。
但你试试测试用例[4,5,6]或者空数组[],本地运行同样会触发list index out of range错误——不信你自己跑一遍就知道了!
CodingBat为什么会报错?
因为CodingBat的测试用例覆盖了所有边界情况:
- 长度小于3的数组(比如空数组、
[1]、[1,2]) - 长度大于3但末尾没有
1、2、3的数组(比如[5,6,7,8])
这些情况都会让循环执行到i的最大值,比如数组长度为2时,i会取到1,这时候访问nums[i+1]就是nums[2],而数组只有索引0和1,自然就触发索引越界了。
关键总结
写这种需要访问后续元素的循环时,一定要提前计算好循环的终止条件,确保所有后续索引都在列表的有效范围内。这里要检查3个连续元素,所以循环的结束值必须是len(nums)-2,避免出现i+2超出列表最大索引的情况。
内容的提问来源于stack exchange,提问作者JackieBoy

