IndexError: List Index Out of Range — What It Means and How to Fix It

The indexerror: list index out of range error is one of the most common errors Python developers encounter, whether they are writing their first loop or debugging a complex data pipeline. It has a clear meaning, and once you understand why Python raises it, you can fix it fast and prevent it from coming back. The error appears when your code tries to access a position in a list using an index number that does not exist in that list. Python lists are zero-indexed, meaning the first element is at index 0, not index 1. If your list has five elements but you ask for the element at position 5, Python raises this error because position 5 does not exist. This guide covers every form of the error, the code patterns that cause it, and the fixes for each one.

indexerror: list index out of range


Why Python Raises This Error: The Core Concept

Python lists are ordered sequences. Each element sits at a numbered position called an index. The indexing starts at 0 and ends at the length of the list minus one.

python
fruits = ["apple", "banana", "cherry"]
# Index:      0          1         2
# len(fruits) = 3
# Valid indices: 0, 1, 2
# Invalid:       3, 4, any number >= 3

When you write fruits[3], Python looks for the element at position 3. That position does not exist. Python raises IndexError: list index out of range to tell you the index you used falls outside the valid range.

The same applies to negative indexing. Negative indices count from the end: fruits[-1] gives you "cherry", fruits[-3] gives you "apple". But fruits[-4] raises the same IndexError because there is no fourth-from-last element in a three-element list.


The Most Common Patterns That Cause This Error

Using len() as an Index

This is the most frequent mistake. It comes from the off-by-one nature of Python’s indexing.

python
fruits = ["apple", "banana", "cherry"]
print(fruits[len(fruits)])  # IndexError

len(fruits) returns 3. The valid indices are 0, 1, and 2. Index 3 does not exist. The fix is to subtract 1:

python
print(fruits[len(fruits) - 1])  # "cherry"
# Or more simply:
print(fruits[-1])  # "cherry"

Loop Index Out of Sync with List Length

Loops that use a range not based on the actual list length often cause the list index out of range error.

python
numbers = [10, 20, 30]
for i in range(5):       # range(5) produces 0, 1, 2, 3, 4
    print(numbers[i])    # Fails at i=3

Fix: base the range on the actual list length:

python
for i in range(len(numbers)):    # range(3) produces 0, 1, 2
    print(numbers[i])

Or better, iterate directly:

python
for number in numbers:
    print(number)

Direct iteration is cleaner, less error-prone, and the preferred Python style when you do not need the index value.

Accessing an Empty List

When a list is empty, every index is out of range. This often happens when you assume a function or operation returned results, but it returned nothing.

python
results = []
print(results[0])  # IndexError

Fix: check whether the list has elements before accessing it:

python
if results:
    print(results[0])
else:
    print("List is empty")

Nested List Index Problems

Accessing nested lists (lists inside lists) doubles the opportunity for index errors.

python
data = [[1, 2], [3, 4], [5, 6]]
print(data[3][0])   # IndexError: outer list has no index 3
print(data[0][5])   # IndexError: inner list has no index 5

Fix: validate both dimensions before accessing:

python
if len(data) > 3 and len(data[3]) > 0:
    print(data[3][0])

Modifying a List While Iterating Over It

Removing items from a list while looping through it shifts the indices, which causes the loop to skip elements or run past the end of the list.

python
items = [1, 2, 3, 4, 5]
for i in range(len(items)):
    if items[i] % 2 == 0:
        items.remove(items[i])  # Modifies list while iterating

This raises IndexError: list index out of range when the list shrinks during the loop. The fix is to iterate over a copy of the list or build a new list instead of modifying in place:

python
items = [x for x in items if x % 2 != 0]

IndexError: List Assignment Index Out of Range

The indexerror: list assignment index out of range is a variant that appears when you try to assign a value to an index that does not exist yet.

python
my_list = [1, 2, 3]
my_list[5] = 10  # IndexError: list assignment index out of range

Python lists do not auto-expand when you assign to an out-of-range index the way some other languages do. Index 5 does not exist, so the assignment fails.

Fix: use .append() to add to the end:

python
my_list.append(10)

Fix: use .insert() to add at a specific position:

python
my_list.insert(3, 10)  # Inserts 10 at index 3

Fix: pre-populate the list to the required size:

python
my_list = [None] * 6   # Creates [None, None, None, None, None, None]
my_list[5] = 10        # Now works fine

The assignment variant catches a lot of people coming from languages like JavaScript, where arrays extend automatically when you assign to a new index.


Python IndexError List Index Out of Range Fix: The Safe Access Patterns

When you are working with lists where the index might not always be valid, build the safety check into the access pattern.

Using try/except

python
my_list = [10, 20, 30]

try:
    value = my_list[5]
except IndexError:
    value = None   # or a default value
    print("Index out of range, using default")

This is the cleanest pattern when you expect the error might occur legitimately and want to handle it without crashing.

Checking Length Before Access

python
index = 5
if index < len(my_list):
    value = my_list[index]
else:
    value = None

This is more explicit and works well when you want to make the guard condition visible in the code.

Using .get() via a Dictionary Instead of a List

If you find yourself frequently accessing lists by index with uncertain validity, consider whether a dictionary with explicit keys would serve better. Dictionaries return None by default when you use .get() on a missing key, which avoids the error entirely.

python
data = {0: "apple", 1: "banana", 2: "cherry"}
value = data.get(5, "not found")   # Returns "not found" instead of raising

Single Positional Indexer Is Out-of-Bounds: The Pandas Version

If you work with pandas DataFrames and Series, you will encounter single positional indexer is out-of-bounds as the pandas equivalent of the standard Python IndexError. It appears when you use .iloc[] to access a row or column position that does not exist.

python
import pandas as pd

df = pd.DataFrame({"name": ["Alice", "Bob"], "score": [90, 85]})
print(df.iloc[5])   # IndexError: single positional indexer is out-of-bounds

The DataFrame has two rows (at positions 0 and 1). Position 5 does not exist.

Common causes:

  • Slicing a DataFrame down to fewer rows than expected, then using a hardcoded .iloc[] position
  • Filtering a DataFrame and then assuming it still has the same row count
  • Iterating over DataFrame rows with a counter that exceeds the filtered length

Fix: check the DataFrame length before positional access:

python
if len(df) > 5:
    print(df.iloc[5])

Fix: use .iloc[-1] for the last row safely:

python
print(df.iloc[-1])   # Always gives the last row, regardless of length

Fix: reset the index after filtering:

When you filter a DataFrame, the original integer index is preserved but the positional order changes. Using .reset_index(drop=True) gives you a clean 0-based positional index that matches the new length.

python
filtered_df = df[df["score"] > 80].reset_index(drop=True)
print(filtered_df.iloc[0])   # Now safely the first filtered row

Debugging IndexErrors Faster: A Checklist

When you hit indexerror: list index out of range and are not immediately sure why, run through this checklist:

  • Print the list length at the point where the error occurs: print(len(my_list))
  • Print the index value you are using: print(index)
  • Check whether the list is empty: if not my_list: ...
  • Verify loop range: confirm your range() call matches the list it is indexing
  • Check for list modification inside a loop: look for .remove(), .pop(), or .append() inside loops that also access by index
  • In pandas: print len(df) and df.shape before .iloc[] calls

Most IndexErrors become obvious the moment you print the length and the index side by side.


Key Takeaways

  • IndexError: list index out of range means you accessed a list at a position that does not exist. Python lists are zero-indexed: a list of length 3 has valid indices 0, 1, and 2.
  • The most frequent cause is using len(list) as an index. Use len(list) - 1 or list[-1] for the last element.
  • indexerror: list assignment index out of range occurs when you assign to an index that does not exist. Use .append() or .insert(), or pre-populate the list.
  • python indexerror list index out of range fix patterns: use try/except IndexError, check length before access, or iterate directly with for item in list instead of indexing.
  • single positional indexer is out-of-bounds is the pandas version, raised by .iloc[] when the row or column position does not exist. Check len(df) before access and use .reset_index() after filtering.
  • When debugging, print the list length and the index value at the same time. The gap between them is always the answer.

For developers building Python tools and data pipelines, understanding how software environments and updates affect code behavior is useful background. When working across different Python versions and tracking dependency changes, project management and tracking tools keep complex development work organized. And for teams building applications on top of Python data tools, mobile and app development principles apply when shipping code that depends on reliable list and data access patterns.