diff options
author | Raymond Hettinger <python@rcn.com> | 2004-06-12 22:48:46 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2004-06-12 22:48:46 (GMT) |
commit | c929766361b4e0ea5bf5dc625e326fb954956f0b (patch) | |
tree | 4ed92088a95e3a8da16edbd93c69d2dfea41ff7e /Modules | |
parent | 84a7f0077c4332a36825366977a73b2cae9bc21e (diff) | |
download | cpython-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')
-rw-r--r-- | Modules/_heapqmodule.c | 76 |
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 */ }; |