// Python
IndexError: list index out of range in Python, and how to fix it
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 asking for [3] fails. Python stops at that line and names it, which makes this one of the easier errors to fix once you know where to look.
What it looks like
scores = [90, 75, 60]
print(scores[0])
print(scores[3])
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 rangeThe last line of the traceback is the error, and the line above it is the code that failed. Here it is scores[3] on line 3.
The four usual causes
1. 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].
2. A loop that goes one step too far. range(len(items) + 1) or a hand-written counter that runs past the end:
scores = [90, 75, 60]
for i in range(len(scores) + 1):
print(scores[i])
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 rangeLoop over the list itself instead, and there is no index to get wrong:
scores = [90, 75, 60]
for score in scores:
print(score)
scores = [90, 75, 60]
for score in scores:
print(score)Output
90 75 60
When you need the position as well, enumerate gives you both: for i, score in enumerate(scores):.
3. An empty list. Code that reads items[0] works until the day the list is empty. Check first:
results = []
first = results[0] if results else None
print(first)
results = []
first = results[0] if results else None
print(first)Output
None
4. Changing a list while looping over its positions. Removing items shortens the list, but range(len(items)) was worked out before the loop started. Build a new list instead of deleting from the one you are looping over: kept = [x for x in items if x > 0].
Negative positions stop somewhere too
Counting from the end is how items[-1] reaches the last item, but that range has an edge as well. A list of three has -1, -2 and -3, and one step further fails the same way. So does -1 on an empty list, which is why the empty-list check above matters here too:
scores = [90, 75, 60]
print(scores[-1], scores[-3])
print(scores[-4])
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 rangeWhen a short list is normal
Sometimes the list is meant to be short, such as the results of a search that found nothing. Then there is no off-by-one to fix, and catching the error is a fair answer. 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")
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, so use this only where a short or empty list is an ordinary case.
The quick way to find the bad index
Print the length and the index just before the line that fails:
scores = [90, 75, 60]
i = 3
print(len(scores), i)
scores = [90, 75, 60]
i = 3
print(len(scores), i)Output
3 3
If the index is equal to or bigger than the length, that is your error.