Суть этой ошибки очень проста - попытка обратиться к элементу списка/массива с несуществующим индексом.
Пример:
lst = [1, 2, 3]print(lst[3])
вывод:
----> 2 print(lst[3])IndexError: list index out of range
Указанный в примере список имеет три элемента. Индексация в Python начинается с 0 и заканчивается n-1, где n - число элементов списка (AKA длина списка). Соответственно для списка lst валидными индексами являются: 0, 1 и 2.
В Python также имеется возможность индексации от конца списка. В этом случае используются отрицательные индексы: -1 - последний элемент, -2 - второй с конца элемент, ..., -n-1 - второй с начала, -n - первый с начала.
Т.е. если указать отрицательный индекс, значение которого превышает длину списка мы получим всё ту же ошибку:
In [2]: lst[-4]---------------------------------------------------------------------------IndexError Traceback (most recent call last)<ipython-input-2-ad46a138c96e> in <module>----> 1 lst[-4]IndexError: list index out of range
В реальной жизни (коде) эта ошибку чаще всего возникает в следующих ситуациях:
- если список пустой:
lst = []; first = lst[0] - в циклах - когда переменная итерирования (по индексам) дополнительно изменяется или когда используются глобальные переменные
- в циклах при использовании вложенных списков - когда перепутаны индексы строк и столбцов
- в циклах при использовании вложенных списков - когда размерности вложенных списков неодинаковые и код этого не учитывает. Пример:
data = [[1,2,3], [4,5], [6,7,8]] - если попытаться обратиться к элементу с индексом 2 во втором списке ([4,5]) мы получим IndexError - в циклах - при изменении длины списка в момент итерирования по нему. Классический пример - попытка удаления элементов списка при итерировании по нему.
Поиск и устранения ошибки начинать нужно всегда с того, чтобы внимательно прочитать сообщение об ошибке (error traceback).
Пример скрипта (test.py), в котором переменная итерирования цикла for <variable> изменяется (так делать нельзя):
lst = [1,2,3]res = []for i in range(len(lst)): i += 1 # <--- НЕ ИЗМЕНЯЙТЕ переменную итерирования! res.append(lst[i] ** 2)
Ошибка:
Traceback (most recent call last): File ""test.py"", line 6, in <module> res.append(lst[i] ** 2)IndexError: list index out of range
Обратите внимание что в сообщении об ошибке указан номер ошибочной строки кода - File ""test.py"", line 6 и сама строка, вызвавшая ошибку: res.append(lst[i] ** 2). Опять же в реальном коде ошибка часто возникает в функциях, которые вызываются из других функций/модулей/классов. Python покажет в сообщении об ошибке весь стек вызовов - это здорово помогает при отладке кода в больших проектах.
После этого - мы точно знаем в каком месте кода возникает ошибка и можем добавить в код отладочную информацию, например напечатать значения индекса, который вызвал ошибку, понять почему используется неправильный индекс и исправить ошибку.