HOWTO · Python

How to Check if Index Exists in Python List

This tutorial demonstrates various ways to check if an index exists in a list in Python.

On this page

Python lists use zero-based indexing, so the first item is at index 0. For a nonnegative index, check 0 <= index < len(items) before access. If you are already trying to retrieve an item, catch IndexError around that access. Python also accepts indexes from the end of a list, so the complete valid range is -len(items) through len(items) - 1.

Check an Index With a Bounds Test

Use a bounds test when you need to validate an index before accessing or updating a list. The test 0 <= index < len(items) includes the first index and excludes the list length, because len(items) is one past the final position.

Run this example:

items = ["Apple", "Banana", "Pineapple"]
index = 1

if 0 <= index < len(items):
    print(f"{items[index]} is at index {index}.")
else:
    print(f"No item at index {index}.")
Banana is at index 1.

This check is clear when a nonnegative, integer-like index is expected. The comparison checks only the value’s range; it does not verify that the value is a valid list index. For example, 1.0 passes 0 <= index < len(items), but items[1.0] raises TypeError. Validate the index type separately before treating a positive result as proof that access will work. This check also does not accept negative indexes, even though Python list access does. If callers may pass negative values, use the full range in the reusable helper below or normalize the index according to your application’s needs.

The condition returns False when the index is outside the list. This example shows both outcomes for the same three-item list:

items = ["Apple", "Banana", "Pineapple"]
for index in (1, 3):
    if 0 <= index < len(items):
        print(f"{index}: {items[index]}")
    else:
        print(f"{index}: no item")
1: Banana
3: no item

Check an Index by Catching IndexError

When retrieving the item is the goal, attempt the access and handle IndexError. Keep the try block narrow so that the handler only covers the operation that can raise this indexing error. Other errors, such as a TypeError from an index that is not an integer, are not hidden by this handler.

items = ["Apple", "Banana", "Pineapple"]
index = 2

try:
    item = items[index]
except IndexError:
    print("No item at that index.")
else:
    print(f"Found {item} at index {index}.")
Found Pineapple at index 2.

This pattern checks access and retrieves the value in one operation. A separate bounds test cannot guarantee a later access will succeed if another part of a program changes the list between checking and using it; catch the access error when that possibility matters.

This example shows the handler for an index past the final position:

items = ["Apple", "Banana", "Pineapple"]
index = 3

try:
    item = items[index]
except IndexError:
    print(f"No item at index {index}.")
No item at index 3.

Create a Reusable Index Check

Put the full list-index range in a helper when the same check is needed in several places. For a list of length n, Python accepts indexes from -n up to, but not including, n.

def index_exists(items, index):
    return -len(items) <= index < len(items)


fruits = ["Apple", "Banana", "Pineapple"]
for index in (2, -1, 3, -4):
    print(f"{index}: {index_exists(fruits, index)}")
2: True
-1: True
3: False
-4: False

The helper assumes an integer-like index and checks only its range, including valid negative indexes. A float such as 1.0 can pass this comparison even though items[1.0] raises TypeError; validate the index type separately before treating True as proof that access will work. Use items[index] after a positive result to retrieve the item. If the list can change between the check and access, the result can become stale; use a try block around the access instead.

Handle Negative and Invalid Indexes

Negative indexes count backward from the end: -1 selects the last item and -len(items) selects the first. A list with no elements has no valid index, since its length is zero and there is no integer between -0 inclusive and 0 exclusive. Values outside the valid range raise IndexError when used to access a list.

Indexes must also be integer-like. A float such as 1.0 may pass a range comparison, but it is not a valid list index and causes TypeError when used for access; a string is also not a valid list index. Catching only IndexError will not handle these type mismatches. If your function accepts data from outside your code, validate its type separately before relying on a bounds check, or handle the exact errors that your interface promises to accept. Avoid converting arbitrary values to integers without deciding whether truncation or parsing matches the caller’s intent.

Choose the Right Approach

Use a bounds check when you want to branch before accessing a nonnegative index, or use the full negative-to-positive range when negative indexes are part of the interface. Use try/except IndexError when the access itself is the operation and you want to respond if it has no item. The reusable helper is useful when the same range check appears repeatedly, but it does not retrieve an item and cannot protect a later access from a changed list.

IndexError specifically signals that an integer index is outside the list’s available positions. A non-integer index raises TypeError, so keep that distinction in mind when validating untrusted input. These approaches let you choose between checking a position up front and handling failure at the point of access.