Python - IndexError: list index out of range NOT being thrown when it should be

Python - IndexError: list index out of range NOT being thrown when it should be

不确定这是因为 Jupyter Notebook 还是 Python 处理了异常,但我正在和朋友一起解决涉及算法的问题

在编写代码时,我使用了 Python!

exampleList = ['a', 'b', 'c', 'd', 'e']

for i in range(0, len(exampleList)):
    for j in range(i + 1, len(exampleList)):
        print(exampleList[i], exampleList[j])

基本上,争论是..这段代码(类似的,我用一个简单的例子来说明)涉及两个 for 循环必须抛出错误!因为,索引 i 达到了 len(exampleList) - 1,而索引 j 技术上将变为 len(exampleList),到那时,print(exampleList[i], exampleList[j]) 将无法工作!看起来 运行 代码确实可以完美地打印出来,而且我认为可以处理 IndexError: list index out of range 异常!

我的问题是..这应该是 Python 中的预期行为吗?因为和我辩论的人最后告诉我 'The people conducting your interview notice these things! You must be able to explain every line.'

我想了解这部分是如何处理的,这样我就可以解释为什么这不会引发错误!

您误解了 range() 的工作原理。

Range() 在第一个小于给定停止值的值处停止计数,在您的情况下等同于 len(exampleList)-1

注意 exampleList[i] 怎么从来不是 e?一旦您的第一个 for 循环命中 len(exampleList) - 1,内部循环就会失败,因为它正在检查 i + 1 是否小于 exampleList 的长度(实际上不是),因此永远不会到达打印语句导致异常不被抛出。

range函数包含下限,但不包含上限。

您的示例列表有 5 个元素。这意味着第一个循环是运行range(0,5),使得最大值i=4。这使得第二个循环的最大值为 range(5,5),这是一个空列表。迭代空列表会导致 0 次迭代。

>>> exampleList = ['a', 'b', 'c', 'd', 'e']
>>> len(exampleList)
5
>>> range(0, 5)
[0, 1, 2, 3, 4]
>>> range(5,5)
[]

Python 没有错。当尝试访问 exampleList[5] 时,异常只会成为一个问题,循环从不请求它。重要的是要记住 range() 不包括上限,但包括下限。​​

下面我在右边加了一些评论来说明

exampleList = ['a', 'b', 'c', 'd', 'e']

for i in range(0, len(exampleList)): # includes [0, 1, 2, 3, 4]
    for j in range(i + 1, len(exampleList)): # includes all numbers in range[0,4] greater than i
        print(exampleList[i], exampleList[j]) # will never exceed 4

在您的示例代码中,j 永远不会等于 len(exampleList)。你说 j in range(i + 1, len(exampleList)),这意味着 j 也总是小于 len(exampleList)。并且,如果 i+1 >= len(exampleList),范围将为空,因为 range(m, n) 其中 m >= n 始终为空。

所以错误永远不会被抛出,因为错误的代码永远不会被执行。

对于这种情况,我们有 len(array) = 5.

第一个循环中的范围函数将迭代 return 5 个值 - [0, 1, 2, 3, 4]。也就是说期号应该是最后一个,4,对吧?

但实际上,当您尝试进入第二个循环时,range(4 + 1, 5) 本质上会 return 一个空白的数字列表,因此它根本不会 运行 循环的内容。 因此,没有错误。

在最外层循环的最后一次迭代中,j 将开始等于 len(example)。因此,在本次迭代中甚至不执行 j-loop。因为范围在 len(example) 和 len(example) - 1 之间。