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 binary_search in searches/binary_search.py when the input list is not in non-decreasing ascending order. Binary search's O(log n) correctness depends entirely on the precondition that the collection is sorted, so the function defensively checks every adjacent pair with itertools.pairwise and rejects the input up front rather than silently returning a wrong index. If you see this error, the list you passed has at least one element greater than its successor.

Source

Thrown at searches/binary_search.py:201

    Be careful collection must be ascending sorted otherwise, the result will be
    unpredictable

    :param sorted_collection: some ascending sorted collection with comparable items
    :param item: item value to search
    :return: index of the found item or -1 if the item is not found

    Examples:
    >>> binary_search([0, 5, 7, 10, 15], 0)
    0
    >>> binary_search([0, 5, 7, 10, 15], 15)
    4
    >>> binary_search([0, 5, 7, 10, 15], 5)
    1
    >>> binary_search([0, 5, 7, 10, 15], 6)
    -1
    """
    if any(a > b for a, b in pairwise(sorted_collection)):
        raise ValueError("sorted_collection must be sorted in ascending order")
    left = 0
    right = len(sorted_collection) - 1

    while left <= right:
        midpoint = left + (right - left) // 2
        current_item = sorted_collection[midpoint]
        if current_item == item:
            return midpoint
        elif item < current_item:
            right = midpoint - 1
        else:
            left = midpoint + 1
    return -1


def binary_search_std_lib(sorted_collection: list[int], item: int) -> int:
    """Pure implementation of a binary search algorithm in Python using stdlib

View on GitHub (pinned to f5988cc097)

Solutions

  1. Sort the collection before searching: binary_search(sorted_collection := sorted(data), item).
  2. If duplicates exist, remember non-decreasing order is fine ([1,2,2,3] passes); only actual inversions fail.
  3. If you must search unsorted data, use a linear search (e.g. searches/linear_search.py) or index.find on a sorted copy.
  4. Keep data sorted at insertion time so the precondition holds by construction.

Example fix

# before
idx = binary_search(data, 42)  # data = [15, 10, 7, 5, 0]

# after
data = sorted(data)
idx = binary_search(data, 42)
Defensive patterns

Strategy: validation

Validate before calling

from itertools import pairwise

def is_ascending(lst):
    return all(a <= b for a, b in pairwise(lst))

assert is_ascending(data), 'data must be sorted before binary_search'

Type guard

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

Try / catch

try:
    idx = binary_search(data, item)
except ValueError:
    data = sorted(data)
    idx = binary_search(data, item)

Prevention

When it happens

Trigger: binary_search([10, 5, 7, 10, 15], 5); passing a list sorted with sort(reverse=True); passing a list after appending a smaller element to an already-sorted list; binary_search(list(d.keys()), item) where keys were never sorted.

Common situations: Forgetting to call sorted() before searching; mixing ascending and descending data from an API; reusing a list that an earlier code path sorted differently; assuming database or CSV rows arrive sorted when they do not.

Related errors


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