krahets/hello-algo · error · IndexError

Index out of bounds

Error message

Index out of bounds

What it means

IndexError 'Index out of bounds' raised by MyList.get. The list only exposes indices [0, _size); anything below 0 or >= _size is rejected even if the backing array has spare capacity up to _capacity.

Source

Thrown at en/codes/python/chapter_array_and_linkedlist/my_list.py:30

        """Constructor"""
        self._capacity: int = 10  # List capacity
        self._arr: list[int] = [0] * self._capacity  # Array (stores list elements)
        self._size: int = 0  # List length (current number of elements)
        self._extend_ratio: int = 2  # Multiple by which the list capacity is extended each time

    def size(self) -> int:
        """Get list length (current number of elements)"""
        return self._size

    def capacity(self) -> int:
        """Get list capacity"""
        return self._capacity

    def get(self, index: int) -> int:
        """Access element"""
        # If the index is out of bounds, throw an exception, as below
        if index < 0 or index >= self._size:
            raise IndexError("Index out of bounds")
        return self._arr[index]

    def set(self, num: int, index: int):
        """Update element"""
        if index < 0 or index >= self._size:
            raise IndexError("Index out of bounds")
        self._arr[index] = num

    def add(self, num: int):
        """Add element at the end"""
        # When the number of elements exceeds capacity, trigger the extension mechanism
        if self.size() == self.capacity():
            self.extend_capacity()
        self._arr[self._size] = num
        self._size += 1

    def insert(self, num: int, index: int):
        """Insert element in the middle"""

View on GitHub (pinned to 69932aed18)

Solutions

  1. Validate 0 <= index < lst.size() before get.
  2. Use lst.size() (not capacity()) as the loop bound.
  3. After remove/insert, recompute indices rather than reusing them.

Example fix

// before
val = lst.get(i)  # i may equal size
// after
if 0 <= i < lst.size():
    val = lst.get(i)
Defensive patterns

Strategy: validation

Validate before calling

def safe_get(lst, index):
    if 0 <= index < lst.size():
        return lst.get(index)
    raise IndexError(f"index {index} out of [0, {lst.size()})")

Type guard

def valid_list_index(lst, index) -> bool:
    return isinstance(index, int) and 0 <= index < lst.size()

Try / catch

try:
    val = lst.get(i)
except IndexError:
    val = None

Prevention

When it happens

Trigger: Calling lst.get(index) with index < 0 or index >= lst.size().

Common situations: Using the backing capacity instead of size as the upper bound; off-by-one in a for-range; reading an index after a remove shifted the elements.

Related errors


AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13). Data as JSON: /api/errors/c7842191ffdbba0c. Report an issue: GitHub.