Home/Blog/Python

// Python

IndexError: list index out of range in Python, and how to fix it

Every example on this page was run on 12 October 2026 in Python 3.14, and the output under each one is what it printed. How we test these posts.

IndexError: list index out of range means you asked a list for a position it does not have. A list of three items has positions 0, 1 and 2, so items[3] fails, and so does any index from len(items) up. The usual fixes are to loop over the list itself instead of its positions, to reach the last item with items[-1], and to check that the list is not empty before reading items[0].

What does IndexError: list index out of range mean?

IndexError: list index out of range means the index was equal to or bigger than the list’s length, or more negative than -len(items). Python stops at that line and names it:

scores = [90, 75, 60]
print(scores[0])
print(scores[3])

Output

90
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    print(scores[3])
          ~~~~~~^^^
IndexError: list index out of range

The last line of the traceback is the error, and the line above it is the code that failed, here scores[3] on line 3. So yes, the error does mean your list is shorter than the code assumed: scores[3] needs at least four items, and scores has three.

List index out of range in a for loop: why does the loop go too far?

A for loop gives list index out of range when it counts positions past the end of the list. range(len(items) + 1), or a hand-written counter that runs one step too far, reads a position that does not exist on its last pass:

scores = [90, 75, 60]
for i in range(len(scores) + 1):
    print(scores[i])

Output

90
75
60
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    print(scores[i])
          ~~~~~~^^^
IndexError: list index out of range

Loop over the list itself instead, and there is no index to get wrong:

scores = [90, 75, 60]
for score in scores:
    print(score)

for i, score in enumerate(scores):
    print(i, score)

Output

90
75
60
0 90
1 75
2 60

When you need the position as well, enumerate gives you both, always within range. Three more mistakes cause the same error, in loops and out of them.

Counting from one

Positions start at zero, so the last item of a list is at len(items) - 1, not len(items). Python has a shorter way to ask for it: items[-1].

Removing items while you loop over positions

Removing items shortens the list, but range(len(items)) was worked out before the loop started, so the last passes ask for positions that are gone. Build a new list instead of deleting from the one you are looping over: kept = [x for x in items if x > 0].

Two lists of different lengths

A loop over range(len(names)) that also reads ages[i] fails as soon as ages is shorter. Loop over zip(names, ages) instead, which stops at the end of the shorter list.

Why does an empty list give list index out of range?

An empty list gives list index out of range for every index, [0] and [-1] included, because it has no positions at all. Code that reads items[0] works until the day the list is empty, such as a search that found nothing. Check first:

results = []
first = results[0] if results else None
print(first)

Output

None

Negative positions stop somewhere too. A list of three has -1, -2 and -3, and one step further fails the same way:

scores = [90, 75, 60]
print(scores[-1], scores[-3])
print(scores[-4])

Output

60 90
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    print(scores[-4])
          ~~~~~~^^^^
IndexError: list index out of range

A script that reads sys.argv[1] and was started without an argument fails the same way, because sys.argv then holds only the script’s name. Check len(sys.argv) before you read it.

What do tuple index out of range and pop from empty list mean?

tuple index out of range and pop from empty list are the same IndexError from a different place. A tuple has fixed positions just like a list, pop() on an empty list has nothing to remove, and pop(i) needs i to exist. str.format() raises one too when the string has more {} than you gave it values:

cases = {
    "point[2]": lambda: (3, 4)[2],
    "[].pop()": lambda: [].pop(),
    "[1, 2].pop(5)": lambda: [1, 2].pop(5),
    "'{} {}'.format('a')": lambda: "{} {}".format("a"),
}
for code, run in cases.items():
    try:
        run()
    except IndexError as e:
        print(f"{code}: {e}")

Output

point[2]: tuple index out of range
[].pop(): pop from empty list
[1, 2].pop(5): pop index out of range
'{} {}'.format('a'): Replacement index 1 out of range for positional args tuple

The fixes are the ones above: check the length, or test if stack: before stack.pop(). The Python tutorial on lists covers pop() and the other list methods.

Should I catch IndexError with try and except?

Catching IndexError with try and except is a fair answer only when a short list is normal, not a bug. Keep the try around the one line that can fail, and say what happens when it does:

scores = [90, 75, 60]
try:
    print(scores[3])
except IndexError:
    print("no fourth score")

Output

no fourth score

Wrapping a whole function in try hides real bugs along with the error you expected. When the short list is a mistake, fix the index instead.

How do I find which index is out of range?

Find the bad index by printing the index and the length just before the line that fails. An f-string with = labels each value for you:

scores = [90, 75, 60]
i = 3
print(f"{i=} {len(scores)=}")

Output

i=3 len(scores)=3

If the index is equal to or bigger than the length, that is your error. The IndexError entry in the Python docs gives the full rule.

IndexError: list assignment index out of range comes from items[i] = value when position i does not exist yet: a list does not grow when you assign past its end, so use append(). IndexError: string index out of range is the same mistake on a string, such as word[len(word)].

If the list itself is None, Python raises TypeError: ‘NoneType’ object is not subscriptable instead. C makes the same mistake much harder to see, because it has no check at all: array index out of bounds in C explains why.