TheAlgorithms/Python · error · IndexError

list index out of range

Error message

list index out of range

What it means

Raised by find_min_recursive() in maths/find_min.py when left or right falls outside -len(nums) <= idx < len(nums). The recursion treats right as an inclusive element index (base case left == right returns nums[left]), so the slice-style call right = len(nums) is out of range and triggers IndexError('list index out of range'); negative indices are allowed down to -len(nums) but not one further.

Source

Thrown at maths/find_min.py:72

    Traceback (most recent call last):
        ...
    IndexError: list index out of range
    >>> find_min_recursive(nums, -len(nums), -1) == min(nums)
    True
    >>> find_min_recursive(nums, -len(nums) - 1, -1) == min(nums)
    Traceback (most recent call last):
        ...
    IndexError: list index out of range
    """
    if len(nums) == 0:
        raise ValueError("find_min_recursive() arg is an empty sequence")
    if (
        left >= len(nums)
        or left < -len(nums)
        or right >= len(nums)
        or right < -len(nums)
    ):
        raise IndexError("list index out of range")
    if left == right:
        return nums[left]
    mid = (left + right) >> 1  # the middle
    left_min = find_min_recursive(nums, left, mid)  # find min in range[left, mid]
    right_min = find_min_recursive(
        nums, mid + 1, right
    )  # find min in range[mid + 1, right]

    return left_min if left_min <= right_min else right_min


if __name__ == "__main__":
    import doctest

    doctest.testmod(verbose=True)

View on GitHub (pinned to f5988cc097)

Solutions

  1. Pass inclusive bounds: find_min_recursive(nums, 0, len(nums) - 1) or (nums, -len(nums), -1).
  2. Subtract 1 from any exclusive stop before passing it as right.
  3. Add a thin wrapper converting [lo, hi) to (lo, hi - 1) if your codebase standardizes on slice semantics.

Example fix

# before
find_min_recursive(nums, 0, len(nums))    # IndexError: right == len(nums)

# after
find_min_recursive(nums, 0, len(nums) - 1)  # inclusive bounds
Defensive patterns

Strategy: validation

Validate before calling

if not (-len(nums) <= left < len(nums) and -len(nums) <= right < len(nums) and left <= right):
    raise IndexError(f'bounds ({left}, {right}) invalid for length {len(nums)}')
lo = find_min_recursive(nums, left, right)

Prevention

When it happens

Trigger: Calling find_min_recursive(nums, 0, len(nums)) with right == len(nums) (shown failing in its doctest), or find_min_recursive(nums, -len(nums) - 1, -1), left >= len(nums), or right < -len(nums). Correct calls use inclusive bounds: (0, len(nums) - 1) or (-len(nums), -1).

Common situations: Half-open [start, stop) bounds from slicing/range habits passed to an inclusive-bounds API — the dominant cause; copy-pasting bounds between helpers with different conventions; index arithmetic like right = left + size without a final -1.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/4ccb381d2c622502. Report an issue: GitHub.