1 /* Bisection algorithms. Drop in replacement for bisect.py
3 Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
9 internal_bisect_right(PyObject
*list
, PyObject
*item
, int lo
, int hi
)
15 hi
= PySequence_Size(list
);
21 litem
= PySequence_GetItem(list
, mid
);
24 res
= PyObject_RichCompareBool(item
, litem
, Py_LT
);
37 bisect_right(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
39 PyObject
*list
, *item
;
43 static const char *keywords
[] = {"a", "x", "lo", "hi", NULL
};
45 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "OO|ii:bisect_right",
46 keywords
, &list
, &item
, &lo
, &hi
))
48 index
= internal_bisect_right(list
, item
, lo
, hi
);
51 return PyInt_FromLong(index
);
54 PyDoc_STRVAR(bisect_right_doc
,
55 "bisect_right(a, x[, lo[, hi]]) -> index\n\
57 Return the index where to insert item x in list a, assuming a is sorted.\n\
59 The return value i is such that all e in a[:i] have e <= x, and all e in\n\
60 a[i:] have e > x. So if x already appears in the list, i points just\n\
61 beyond the rightmost x already there\n\
63 Optional args lo (default 0) and hi (default len(a)) bound the\n\
64 slice of a to be searched.\n");
67 insort_right(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
69 PyObject
*list
, *item
, *result
;
73 static const char *keywords
[] = {"a", "x", "lo", "hi", NULL
};
75 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "OO|ii:insort_right",
76 keywords
, &list
, &item
, &lo
, &hi
))
78 index
= internal_bisect_right(list
, item
, lo
, hi
);
81 if (PyList_Check(list
)) {
82 if (PyList_Insert(list
, index
, item
) < 0)
85 result
= PyObject_CallMethod(list
, "insert", "iO",
95 PyDoc_STRVAR(insort_right_doc
,
96 "insort_right(a, x[, lo[, hi]])\n\
98 Insert item x in list a, and keep it sorted assuming a is sorted.\n\
100 If x is already in a, insert it to the right of the rightmost x.\n\
102 Optional args lo (default 0) and hi (default len(a)) bound the\n\
103 slice of a to be searched.\n");
106 internal_bisect_left(PyObject
*list
, PyObject
*item
, int lo
, int hi
)
112 hi
= PySequence_Size(list
);
118 litem
= PySequence_GetItem(list
, mid
);
121 res
= PyObject_RichCompareBool(litem
, item
, Py_LT
);
134 bisect_left(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
136 PyObject
*list
, *item
;
140 static const char *keywords
[] = {"a", "x", "lo", "hi", NULL
};
142 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "OO|ii:bisect_left",
143 keywords
, &list
, &item
, &lo
, &hi
))
145 index
= internal_bisect_left(list
, item
, lo
, hi
);
148 return PyInt_FromLong(index
);
151 PyDoc_STRVAR(bisect_left_doc
,
152 "bisect_left(a, x[, lo[, hi]]) -> index\n\
154 Return the index where to insert item x in list a, assuming a is sorted.\n\
156 The return value i is such that all e in a[:i] have e < x, and all e in\n\
157 a[i:] have e >= x. So if x already appears in the list, i points just\n\
158 before the leftmost x already there.\n\
160 Optional args lo (default 0) and hi (default len(a)) bound the\n\
161 slice of a to be searched.\n");
164 insort_left(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
166 PyObject
*list
, *item
, *result
;
170 static const char *keywords
[] = {"a", "x", "lo", "hi", NULL
};
172 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "OO|ii:insort_left",
173 keywords
, &list
, &item
, &lo
, &hi
))
175 index
= internal_bisect_left(list
, item
, lo
, hi
);
178 if (PyList_Check(list
)) {
179 if (PyList_Insert(list
, index
, item
) < 0)
182 result
= PyObject_CallMethod(list
, "insert", "iO",
192 PyDoc_STRVAR(insort_left_doc
,
193 "insort_left(a, x[, lo[, hi]])\n\
195 Insert item x in list a, and keep it sorted assuming a is sorted.\n\
197 If x is already in a, insert it to the left of the leftmost x.\n\
199 Optional args lo (default 0) and hi (default len(a)) bound the\n\
200 slice of a to be searched.\n");
202 PyDoc_STRVAR(bisect_doc
, "Alias for bisect_right().\n");
203 PyDoc_STRVAR(insort_doc
, "Alias for insort_right().\n");
205 static PyMethodDef bisect_methods
[] = {
206 {"bisect_right", (PyCFunction
)bisect_right
,
207 METH_VARARGS
|METH_KEYWORDS
, bisect_right_doc
},
208 {"bisect", (PyCFunction
)bisect_right
,
209 METH_VARARGS
|METH_KEYWORDS
, bisect_doc
},
210 {"insort_right", (PyCFunction
)insort_right
,
211 METH_VARARGS
|METH_KEYWORDS
, insort_right_doc
},
212 {"insort", (PyCFunction
)insort_right
,
213 METH_VARARGS
|METH_KEYWORDS
, insort_doc
},
214 {"bisect_left", (PyCFunction
)bisect_left
,
215 METH_VARARGS
|METH_KEYWORDS
, bisect_left_doc
},
216 {"insort_left", (PyCFunction
)insort_left
,
217 METH_VARARGS
|METH_KEYWORDS
, insort_left_doc
},
218 {NULL
, NULL
} /* sentinel */
221 PyDoc_STRVAR(module_doc
,
222 "Bisection algorithms.\n\
224 This module provides support for maintaining a list in sorted order without\n\
225 having to sort the list after each insertion. For long lists of items with\n\
226 expensive comparison operations, this can be an improvement over the more\n\
227 common approach.\n");
234 m
= Py_InitModule3("_bisect", bisect_methods
, module_doc
);