IndexError: list index out of range переводится как «индекс списка вне диапазона». Код обратился к элементу по номеру, а элемента с таким номером в списке нет. Номера в Python начинаются с нуля, поэтому у списка из четырёх элементов есть индексы 0, 1, 2 и 3, а с конца — от -1 до -4. Всё, что за этими границами, даёт IndexError.
У той же ошибки есть родственные сообщения: string index out of range для строк, tuple index out of range для кортежей, list assignment index out of range при записи и pop from empty list для пустого списка. Причины у них общие — разберём их по очереди. Все примеры можно запустить кнопкой прямо на странице.
Четыре элемента — индексы от 0 до 3
Как читать сообщение
Трассировка показывает файл, номер строки и само выражение, а знаки ^ под ним отмечают, где именно случился выход за границы:
cities = ["Москва", "Казань", "Пермь", "Сочи"]
print(len(cities))
print(cities[4])
4
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(cities[4])
~~~~~~^^^
IndexError: list index out of range
Чтобы понять, что пошло не так, достаточно двух чисел: длины списка и индекса, к которому обратился код. Если индекс считается в цикле или приходит из данных, выведи оба через print прямо перед строкой с ошибкой.
Причина 1: счёт с нуля
Самая частая ошибка — взять последний элемент по номеру, равному длине. Последний индекс на единицу меньше: len(cities) - 1. Ещё проще — отрицательный индекс -1, он всегда означает последний элемент. Отрицательные индексы тоже ограничены: у четырёх элементов самый дальний — -4.
cities = ["Москва", "Казань", "Пермь", "Сочи"]
print(cities[len(cities) - 1], cities[-1], cities[-4])
print(cities[-5])
Сочи Сочи Москва
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(cities[-5])
~~~~~~^^^^
IndexError: list index out of range
Причина 2: лишний шаг в цикле
Цикл по индексам легко сделать на шаг длиннее списка — через range(len(...) + 1) или условие i <= len(...) в while. Все элементы печатаются, а на последнем шаге программа падает:
cities = ["Москва", "Казань", "Пермь", "Сочи"]
for i in range(len(cities) + 1):
print(i, cities[i])
0 Москва
1 Казань
2 Пермь
3 Сочи
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(i, cities[i])
~~~~~~^^^
IndexError: list index out of range
Надёжнее вовсе не считать индексы: for city in cities перебирает сами элементы, а если номер всё-таки нужен, его даёт enumerate:
cities = ["Москва", "Казань", "Пермь", "Сочи"]
for number, city in enumerate(cities, start=1):
print(number, city)
1 Москва
2 Казань
3 Пермь
4 Сочи
Так выйти за границы невозможно. Подробнее о переборе — в статье про циклы.
Причина 3: список пустой
У пустого списка нет даже нулевого элемента. Обычно он пустеет незаметно: фильтр ничего не нашёл, файл оказался пустым, пользователь ничего не ввёл. Проверяй, что в списке что-то есть, до обращения к элементам — пустой список в условии считается ложью:
scores = []
print(max(scores) if scores else "оценок пока нет")
print(scores[0])
оценок пока нет
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(scores[0])
~~~~~~^^^
IndexError: list index out of range
Причина 4: split() и sys.argv дали меньше, чем ждали
Строку из ввода часто делят методом split() и берут части по номерам. Если человек ввёл меньше слов, чем ожидала программа, второй части просто нет:
line = "Анна"
parts = line.split()
print(parts)
print("Фамилия:", parts[1])
['Анна']
Traceback (most recent call last):
File "main.py", line 4, in <module>
print("Фамилия:", parts[1])
~~~~~^^^
IndexError: list index out of range
Проверь длину: if len(parts) < 2: print("Введи имя и фамилию через пробел"). О методах строк — в статье про split, join и другие методы.
Тот же случай с аргументами командной строки. sys.argv[0] — имя самой программы, а аргументы начинаются с sys.argv[1]. Запусти скрипт без аргументов — и первого из них нет:
import sys
print(sys.argv)
name = sys.argv[1]
['main.py']
Traceback (most recent call last):
File "main.py", line 4, in <module>
name = sys.argv[1]
~~~~~~~~^^^
IndexError: list index out of range
Проверяй len(sys.argv) и печатай подсказку, как запускать программу, — или возьми модуль argparse, который делает это сам.
Причина 5: элементы удаляют в цикле по индексам
Цикл for i in range(len(numbers)) вычисляет границы один раз, в начале. Если внутри удалять элементы, список становится короче, а индексы продолжают идти до старой длины:
numbers = [3, -1, 4, -5, 9]
for i in range(len(numbers)):
if numbers[i] < 0:
del numbers[i]
Traceback (most recent call last):
File "main.py", line 3, in <module>
if numbers[i] < 0:
~~~~~~~^^^
IndexError: list index out of range
Не меняй список, который перебираешь. Собери новый — списковое включение делает это в одну строку:
numbers = [3, -1, 4, -5, 9]
positive = [n for n in numbers if n >= 0]
print(positive)
[3, 4, 9]
Вложенные списки: какой из индексов лишний
В таблице из списков два индекса: сначала строка, потом столбец. Если ошибка в такой строке, проверь оба — по длине внешнего списка и по длине строки:
grid = [[1, 2, 3], [4, 5, 6]]
print(len(grid), len(grid[0]))
print(grid[1][2])
print(grid[2][1])
2 3
6
Traceback (most recent call last):
File "main.py", line 4, in <module>
print(grid[2][1])
~~~~^^^
IndexError: list index out of range
Знаки ^ стоят под [2]: строки с индексом 2 нет, их всего две. Частая путаница — перепутать порядок и писать grid[столбец][строка].
Другие сообщения IndexError
Строки, кортежи и методы списков сообщают о той же ошибке своими словами. Отдельный случай — запись: присвоить значение несуществующему элементу нельзя, новый элемент добавляют методом append:
checks = [
lambda: "Python"[10],
lambda: (1, 2)[2],
lambda: [].pop(),
]
for check in checks:
try:
check()
except IndexError as exc:
print(f"IndexError: {exc}")
marks = []
try:
marks[0] = 5
except IndexError as exc:
print(f"IndexError: {exc}")
marks.append(5)
print(marks)
IndexError: string index out of range
IndexError: tuple index out of range
IndexError: pop from empty list
IndexError: list assignment index out of range
[5]
Методы списков — append, pop, insert и другие — разобраны в статье о методах списков.
Как получить элемент без ошибки
Срезы за границы не падают: они просто возвращают то, что есть. А если нужен один элемент, который может отсутствовать, проверь длину и подставь значение по умолчанию:
cities = ["Москва", "Казань", "Пермь", "Сочи"]
print(cities[2:10])
print(cities[10:])
print(cities[5] if len(cities) > 5 else None)
['Пермь', 'Сочи']
[]
None
Оборачивать каждое обращение в try/except IndexError не стоит. Ошибка почти всегда значит, что программа неверно посчитала индекс или получила не те данные, а перехват это спрячет. try/except уместен там, где пустой ввод — нормальный сценарий, и ты знаешь, что делать дальше. Подробнее — в статье про try/except.
Частые вопросы
Как переводится list index out of range
«Индекс списка вне диапазона». Код обратился к элементу по номеру, которого в списке нет.
Чем IndexError отличается от KeyError
IndexError — нет элемента с таким номером в списке, строке или кортеже. KeyError — нет такого ключа в словаре. Безопасный способ взять значение из словаря — метод get, о нём в статье про словари.
Почему ошибка не на той строке, где я ошибся
Python падает там, где индекс использован, а посчитан он мог быть раньше: в цикле, в функции, из ввода. Выведи длину списка и индекс перед строкой с ошибкой и иди назад, к месту, где индекс получил это значение.