TheAlgorithms/Python · error · ValueError

sorted_collection must be sorted in ascending order

Error message

sorted_collection must be sorted in ascending order

What it means

Raised by the module-local copy of binary_search_by_recursion inside searches/exponential_search.py when sorted_collection is not in ascending order. exponential_search.py vendors its own recursive binary search rather than importing from binary_search.py, so the same 'sorted_collection must be sorted in ascending order' ValueError exists here as an independent raise site. The guard compares list(sorted_collection) to sorted(sorted_collection) on every recursive call, and right < 0 is normalized to len - 1 before the check.

Source

Thrown at searches/exponential_search.py:46

    :param item: item value to search
    :param left: starting index for the search
    :param right: ending index for the search
    :return: index of the found item or -1 if the item is not found

    Examples:
    >>> binary_search_by_recursion([0, 5, 7, 10, 15], 0, 0, 4)
    0
    >>> binary_search_by_recursion([0, 5, 7, 10, 15], 15, 0, 4)
    4
    >>> binary_search_by_recursion([0, 5, 7, 10, 15], 5, 0, 4)
    1
    >>> binary_search_by_recursion([0, 5, 7, 10, 15], 6, 0, 4)
    -1
    """
    if right < 0:
        right = len(sorted_collection) - 1
    if list(sorted_collection) != sorted(sorted_collection):
        raise ValueError("sorted_collection must be sorted in ascending order")
    if right < left:
        return -1

    midpoint = left + (right - left) // 2

    if sorted_collection[midpoint] == item:
        return midpoint
    elif sorted_collection[midpoint] > item:
        return binary_search_by_recursion(sorted_collection, item, left, midpoint - 1)
    else:
        return binary_search_by_recursion(sorted_collection, item, midpoint + 1, right)


def exponential_search(sorted_collection: list[int], item: int) -> int:
    """
    Pure implementation of an exponential search algorithm in Python.
    For more information, refer to:
    https://en.wikipedia.org/wiki/Exponential_search

View on GitHub (pinned to f5988cc097)

Solutions

  1. Sort the collection before calling: exponential_search(sorted(data), item).
  2. If you are maintaining this code, consider having exponential_search.py import binary_search_by_recursion from searches.binary_search to remove the duplicated raise site.
  3. Validate sortedness once at the top level instead of relying on the per-recursion check.

Example fix

# before
i = exponential_search(data, 7)  # data = [9, 3, 7]

# after
data = sorted(data)
i = exponential_search(data, 7)
Defensive patterns

Strategy: validation

Validate before calling

data = sorted(data)
idx = exponential_search(data, item)  # module validates before recursing

Type guard

def is_ascending(lst: list) -> bool:
    return all(a <= b for a, b in zip(lst, lst[1:]))

Try / catch

try:
    idx = binary_search_by_recursion(data, item, 0, len(data) - 1)
except ValueError:
    data = sorted(data)
    idx = binary_search_by_recursion(data, item, 0, len(data) - 1)

Prevention

When it happens

Trigger: Calling binary_search_by_recursion from exponential_search with unsorted data, e.g. exponential_search([5, 4, 3], 4) fails at this line; direct calls like binary_search_by_recursion([2, 1], 1, 0, 1).

Common situations: Refactoring between binary_search.py and exponential_search.py and assuming they share one implementation (they do not); linting/duplication tools flagging the two copies; fixing the guard in one file but not the other.

Related errors


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