IndexError: list index out of range in Python
This error occurs when attempting to access a list index that is outside the range of 0 to len(list) - 1. Guard access with bounds checking or use iteration.
Root Cause Analysis
This error occurs when Python tries to access an element of a sequence using an integer index, but the provided index falls outside the valid bounds of existing positions.
Cause 1: Off-by-One Errors in Bounds Checking
Python sequences are zero-indexed: a list with n elements contains valid indices from 0 to n - 1. Attempting to access items[len(items)] raises IndexError: list index out of range because index n is one past the end.
Cause 2: Accessing Elements in Empty Lists
When fetching records from an API or database query that returns zero results, accessing results[0] raises IndexError because an empty list has no index 0.
Cause 3: Unbounded While Loops and Index Increments
Manually managing index counters in while loops without verifying termination bounds can lead to index variables exceeding list dimensions.
Cause 4: Negative Indices Beyond Sequence Length
While Python supports negative indexing (items[-1] for the last item), a negative index smaller than -len(items) (e.g. items[-5] on a 3-element list) triggers IndexError.
Reproduction Code (MCVE)
items = ['server_alpha', 'server_beta']
target_index = 5
selected_server = items[target_index]
Solution 1: Guard with Explicit Length and Boundary Checks
Verify that the requested index is within the valid range 0 <= target_index < len(items) before attempting access.
items = ['server_alpha', 'server_beta']
target_index = 5
if 0 <= target_index < len(items):
selected_server = items[target_index]
else:
print(f'Index {target_index} is out of bounds for list of size {len(items)}')
selected_server = None
print(f'Selected: {selected_server}')
Solution 2: Defensive Element Retrieval with try/except IndexError
Wrap direct lookups in a try/except block when handling external or dynamic index queries.
items = ['server_alpha', 'server_beta']
target_index = 5
try:
selected_server = items[target_index]
except IndexError:
print(f'Notice: Index {target_index} not found. Applying fallback.')
selected_server = 'default_server'
print(f'Server: {selected_server}')
Common Mistakes & Edge Cases
1. Modifying Lists While Iterating by Index
Deleting elements (del items[i] or items.pop(i)) while iterating forward alters the length of the list dynamically, causing subsequent index lookups to exceed current bounds. Iterate over a copy or use list comprehensions.
2. Contrasting IndexError vs KeyError
Lists and tuples raise IndexError on missing integer offsets. In contrast, Python dictionaries and pandas Series with non-integer indices raise KeyError when a specified key does not exist.
3. Safe Slice Access Does Not Raise IndexError
Unlike scalar indexing (items[10]), sequence slicing items[10:15] gracefully returns an empty list [] instead of raising IndexError. Use slices when extracting optional sub-ranges.