summaryrefslogtreecommitdiffstats
path: root/Modules/_heapqmodule.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2004-06-12 22:48:46 (GMT)
committerRaymond Hettinger <python@rcn.com>2004-06-12 22:48:46 (GMT)
commitc929766361b4e0ea5bf5dc625e326fb954956f0b (patch)
tree4ed92088a95e3a8da16edbd93c69d2dfea41ff7e /Modules/_heapqmodule.c
parent84a7f0077c4332a36825366977a73b2cae9bc21e (diff)
downloadcpython-c929766361b4e0ea5bf5dc625e326fb954956f0b.zip
cpython-c929766361b4e0ea5bf5dc625e326fb954956f0b.tar.gz
cpython-c929766361b4e0ea5bf5dc625e326fb954956f0b.tar.bz2
Install C version of heapq.nlargest().
Maxheap version of heapq.smallest() is forthcoming.
Diffstat (limited to 'Modules/_heapqmodule.c')
-rw-r--r--Modules/_heapqmodule.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c
index 7455fbc..8fe742f 100644
--- a/Modules/_heapqmodule.c
+++ b/Modules/_heapqmodule.c
@@ -216,6 +216,80 @@ heapify(PyObject *self, PyObject *heap)
PyDoc_STRVAR(heapify_doc,
"Transform list into a heap, in-place, in O(len(heap)) time.");
+static PyObject *
+nlargest(PyObject *self, PyObject *args)
+{
+ PyObject *heap=NULL, *elem, *rv, *iterable, *sol, *it, *oldelem;
+ int i, n;
+
+ if (!PyArg_ParseTuple(args, "Oi:nlargest", &iterable, &n))
+ return NULL;
+
+ it = PyObject_GetIter(iterable);
+ if (it == NULL)
+ return NULL;
+
+ heap = PyList_New(0);
+ if (it == NULL)
+ goto fail;
+
+ for (i=0 ; i<n ; i++ ){
+ elem = PyIter_Next(it);
+ if (elem == NULL)
+ goto sortit;
+ if (PyList_Append(heap, elem) == -1) {
+ Py_DECREF(elem);
+ goto fail;
+ }
+ Py_DECREF(elem);
+ }
+ if (PyList_GET_SIZE(heap) == 0)
+ goto sortit;
+
+ rv = heapify(self, heap);
+ if (rv == NULL)
+ goto fail;
+ Py_DECREF(rv);
+
+ sol = PyList_GET_ITEM(heap, 0);
+ while (1) {
+ elem = PyIter_Next(it);
+ if (elem == NULL) {
+ if (PyErr_Occurred())
+ goto fail;
+ else
+ goto sortit;
+ }
+ if (PyObject_RichCompareBool(elem, sol, Py_LE)) {
+ Py_DECREF(elem);
+ continue;
+ }
+ oldelem = PyList_GET_ITEM(heap, 0);
+ PyList_SET_ITEM(heap, 0, elem);
+ Py_DECREF(oldelem);
+ if (_siftup((PyListObject *)heap, 0) == -1)
+ goto fail;
+ sol = PyList_GET_ITEM(heap, 0);
+ }
+sortit:
+ Py_DECREF(it);
+ if (PyList_Sort(heap) == -1)
+ goto fail;
+ if (PyList_Reverse(heap) == -1)
+ goto fail;
+ return heap;
+
+fail:
+ Py_DECREF(it);
+ Py_XDECREF(heap);
+ return NULL;
+}
+
+PyDoc_STRVAR(nlargest_doc,
+"Find the n largest elements in a dataset.\n\
+\n\
+Equivalent to: sorted(iterable, reverse=True)[:n]\n");
+
static PyMethodDef heapq_methods[] = {
{"heappush", (PyCFunction)heappush,
METH_VARARGS, heappush_doc},
@@ -225,6 +299,8 @@ static PyMethodDef heapq_methods[] = {
METH_VARARGS, heapreplace_doc},
{"heapify", (PyCFunction)heapify,
METH_O, heapify_doc},
+ {"nlargest", (PyCFunction)nlargest,
+ METH_VARARGS, nlargest_doc},
{NULL, NULL} /* sentinel */
};