@@ -216,6 +216,80 @@ heapify(PyObject *self, PyObject *heap)
216216PyDoc_STRVAR (heapify_doc ,
217217"Transform list into a heap, in-place, in O(len(heap)) time." );
218218
219+ static PyObject *
220+ nlargest (PyObject * self , PyObject * args )
221+ {
222+ PyObject * heap = NULL , * elem , * rv , * iterable , * sol , * it , * oldelem ;
223+ int i , n ;
224+
225+ if (!PyArg_ParseTuple (args , "Oi:nlargest" , & iterable , & n ))
226+ return NULL ;
227+
228+ it = PyObject_GetIter (iterable );
229+ if (it == NULL )
230+ return NULL ;
231+
232+ heap = PyList_New (0 );
233+ if (it == NULL )
234+ goto fail ;
235+
236+ for (i = 0 ; i < n ; i ++ ){
237+ elem = PyIter_Next (it );
238+ if (elem == NULL )
239+ goto sortit ;
240+ if (PyList_Append (heap , elem ) == -1 ) {
241+ Py_DECREF (elem );
242+ goto fail ;
243+ }
244+ Py_DECREF (elem );
245+ }
246+ if (PyList_GET_SIZE (heap ) == 0 )
247+ goto sortit ;
248+
249+ rv = heapify (self , heap );
250+ if (rv == NULL )
251+ goto fail ;
252+ Py_DECREF (rv );
253+
254+ sol = PyList_GET_ITEM (heap , 0 );
255+ while (1 ) {
256+ elem = PyIter_Next (it );
257+ if (elem == NULL ) {
258+ if (PyErr_Occurred ())
259+ goto fail ;
260+ else
261+ goto sortit ;
262+ }
263+ if (PyObject_RichCompareBool (elem , sol , Py_LE )) {
264+ Py_DECREF (elem );
265+ continue ;
266+ }
267+ oldelem = PyList_GET_ITEM (heap , 0 );
268+ PyList_SET_ITEM (heap , 0 , elem );
269+ Py_DECREF (oldelem );
270+ if (_siftup ((PyListObject * )heap , 0 ) == -1 )
271+ goto fail ;
272+ sol = PyList_GET_ITEM (heap , 0 );
273+ }
274+ sortit :
275+ Py_DECREF (it );
276+ if (PyList_Sort (heap ) == -1 )
277+ goto fail ;
278+ if (PyList_Reverse (heap ) == -1 )
279+ goto fail ;
280+ return heap ;
281+
282+ fail :
283+ Py_DECREF (it );
284+ Py_XDECREF (heap );
285+ return NULL ;
286+ }
287+
288+ PyDoc_STRVAR (nlargest_doc ,
289+ "Find the n largest elements in a dataset.\n\
290+ \n\
291+ Equivalent to: sorted(iterable, reverse=True)[:n]\n" );
292+
219293static PyMethodDef heapq_methods [] = {
220294 {"heappush" , (PyCFunction )heappush ,
221295 METH_VARARGS , heappush_doc },
@@ -225,6 +299,8 @@ static PyMethodDef heapq_methods[] = {
225299 METH_VARARGS , heapreplace_doc },
226300 {"heapify" , (PyCFunction )heapify ,
227301 METH_O , heapify_doc },
302+ {"nlargest" , (PyCFunction )nlargest ,
303+ METH_VARARGS , nlargest_doc },
228304 {NULL , NULL } /* sentinel */
229305};
230306
0 commit comments