Skip to main content

Modules/_bisect module

Source:

cpython 3.14 @ ab2d84fe1023/Modules/_bisectmodule.c

_bisect is the C acceleration for Lib/bisect.py. It provides O(log n) binary search and sorted-insert operations on Python lists.

Map

LinesSymbolRole
1-80bisect_right_implFind rightmost insertion point
81-160bisect_left_implFind leftmost insertion point
161-250insort_right_impl, insort_left_implBinary search + insert
251-300Module init, key parameter support3.10+ key function

Reading

bisect_right

// CPython: Modules/_bisectmodule.c:38 bisect_right_impl
static Py_ssize_t
bisect_right_impl(PyObject *module, PyObject *list,
PyObject *item, Py_ssize_t lo, Py_ssize_t hi, PyObject *key)
{
while (lo < hi) {
Py_ssize_t mid = ((unsigned)(lo + hi)) >> 1;
PyObject *litem = PyList_GET_ITEM(list, mid);
if (key != Py_None)
litem = PyObject_CallOneArg(key, litem);
int cmp = PyObject_RichCompareBool(item, litem, Py_LT);
if (cmp < 0) return -1; /* error */
if (cmp)
hi = mid;
else
lo = mid + 1;
}
return lo;
}

bisect_right finds the index after any existing entries equal to item. bisect_left finds the index before them. The difference matters when inserting duplicates.

Key function (3.10+)

# CPython: Modules/_bisectmodule.c (Python usage)
import bisect
data = [('a', 1), ('b', 2), ('c', 3)]
pos = bisect.bisect_left(data, 'b', key=lambda x: x[0])
# pos == 1

The key parameter was added in Python 3.10. When provided, it is called on each list element before comparison. The item argument is compared directly (not through key).

insort

// CPython: Modules/_bisectmodule.c:200 insort_right_impl
static PyObject *
insort_right_impl(PyObject *module, PyObject *list,
PyObject *item, Py_ssize_t lo, Py_ssize_t hi, PyObject *key)
{
Py_ssize_t index = bisect_right_impl(module, list, item, lo, hi, key);
if (index < 0) return NULL;
return PyList_Insert(list, index, item);
}

insort calls bisect then list.insert. The insert is O(n) due to shifting; the binary search is only O(log n).

gopy notes

bisect is used by heapq.nlargest/nsmallest (indirectly) and by any code doing sorted-list operations. In gopy it is implemented in module/bisect/ using Go's sort.Search. The key parameter requires calling back into Python for each comparison element.