mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
Implement heapq in terms of less-than (to match list.sort()).
This commit is contained in:
parent
adff65bc3e
commit
6d7702ecd1
3 changed files with 36 additions and 20 deletions
13
Lib/heapq.py
13
Lib/heapq.py
|
|
@ -167,7 +167,7 @@ def heapreplace(heap, item):
|
||||||
|
|
||||||
def heappushpop(heap, item):
|
def heappushpop(heap, item):
|
||||||
"""Fast version of a heappush followed by a heappop."""
|
"""Fast version of a heappush followed by a heappop."""
|
||||||
if heap and item > heap[0]:
|
if heap and heap[0] < item:
|
||||||
item, heap[0] = heap[0], item
|
item, heap[0] = heap[0], item
|
||||||
_siftup(heap, 0)
|
_siftup(heap, 0)
|
||||||
return item
|
return item
|
||||||
|
|
@ -240,10 +240,11 @@ def _siftdown(heap, startpos, pos):
|
||||||
while pos > startpos:
|
while pos > startpos:
|
||||||
parentpos = (pos - 1) >> 1
|
parentpos = (pos - 1) >> 1
|
||||||
parent = heap[parentpos]
|
parent = heap[parentpos]
|
||||||
if parent <= newitem:
|
if newitem < parent:
|
||||||
break
|
heap[pos] = parent
|
||||||
heap[pos] = parent
|
pos = parentpos
|
||||||
pos = parentpos
|
continue
|
||||||
|
break
|
||||||
heap[pos] = newitem
|
heap[pos] = newitem
|
||||||
|
|
||||||
# The child indices of heap index pos are already heaps, and we want to make
|
# The child indices of heap index pos are already heaps, and we want to make
|
||||||
|
|
@ -294,7 +295,7 @@ def _siftup(heap, pos):
|
||||||
while childpos < endpos:
|
while childpos < endpos:
|
||||||
# Set childpos to index of smaller child.
|
# Set childpos to index of smaller child.
|
||||||
rightpos = childpos + 1
|
rightpos = childpos + 1
|
||||||
if rightpos < endpos and heap[rightpos] <= heap[childpos]:
|
if rightpos < endpos and not heap[childpos] < heap[rightpos]:
|
||||||
childpos = rightpos
|
childpos = rightpos
|
||||||
# Move the smaller child up.
|
# Move the smaller child up.
|
||||||
heap[pos] = heap[childpos]
|
heap[pos] = heap[childpos]
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ Core and Builtins
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- The heapq module does comparisons using LT instead of LE. This
|
||||||
|
makes its implementation match that used by list.sort().
|
||||||
|
|
||||||
- Issue #2819: add full-precision summation function to math module,
|
- Issue #2819: add full-precision summation function to math module,
|
||||||
based on Hettinger's ASPN Python Cookbook recipe.
|
based on Hettinger's ASPN Python Cookbook recipe.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,12 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
|
||||||
while (pos > startpos){
|
while (pos > startpos){
|
||||||
parentpos = (pos - 1) >> 1;
|
parentpos = (pos - 1) >> 1;
|
||||||
parent = PyList_GET_ITEM(heap, parentpos);
|
parent = PyList_GET_ITEM(heap, parentpos);
|
||||||
cmp = PyObject_RichCompareBool(parent, newitem, Py_LE);
|
cmp = PyObject_RichCompareBool(newitem, parent, Py_LT);
|
||||||
if (cmp == -1) {
|
if (cmp == -1) {
|
||||||
Py_DECREF(newitem);
|
Py_DECREF(newitem);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (cmp == 1)
|
if (cmp == 0)
|
||||||
break;
|
break;
|
||||||
Py_INCREF(parent);
|
Py_INCREF(parent);
|
||||||
Py_DECREF(PyList_GET_ITEM(heap, pos));
|
Py_DECREF(PyList_GET_ITEM(heap, pos));
|
||||||
|
|
@ -69,14 +69,14 @@ _siftup(PyListObject *heap, Py_ssize_t pos)
|
||||||
rightpos = childpos + 1;
|
rightpos = childpos + 1;
|
||||||
if (rightpos < endpos) {
|
if (rightpos < endpos) {
|
||||||
cmp = PyObject_RichCompareBool(
|
cmp = PyObject_RichCompareBool(
|
||||||
PyList_GET_ITEM(heap, rightpos),
|
|
||||||
PyList_GET_ITEM(heap, childpos),
|
PyList_GET_ITEM(heap, childpos),
|
||||||
Py_LE);
|
PyList_GET_ITEM(heap, rightpos),
|
||||||
|
Py_LT);
|
||||||
if (cmp == -1) {
|
if (cmp == -1) {
|
||||||
Py_DECREF(newitem);
|
Py_DECREF(newitem);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (cmp == 1)
|
if (cmp == 0)
|
||||||
childpos = rightpos;
|
childpos = rightpos;
|
||||||
}
|
}
|
||||||
/* Move the smaller child up. */
|
/* Move the smaller child up. */
|
||||||
|
|
@ -214,10 +214,10 @@ heappushpop(PyObject *self, PyObject *args)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp = PyObject_RichCompareBool(item, PyList_GET_ITEM(heap, 0), Py_LE);
|
cmp = PyObject_RichCompareBool(PyList_GET_ITEM(heap, 0), item, Py_LT);
|
||||||
if (cmp == -1)
|
if (cmp == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (cmp == 1) {
|
if (cmp == 0) {
|
||||||
Py_INCREF(item);
|
Py_INCREF(item);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
@ -270,6 +270,7 @@ nlargest(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem;
|
PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem;
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable))
|
if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -312,7 +313,12 @@ nlargest(PyObject *self, PyObject *args)
|
||||||
else
|
else
|
||||||
goto sortit;
|
goto sortit;
|
||||||
}
|
}
|
||||||
if (PyObject_RichCompareBool(elem, sol, Py_LE)) {
|
cmp = PyObject_RichCompareBool(sol, elem, Py_LT);
|
||||||
|
if (cmp == -1) {
|
||||||
|
Py_DECREF(elem);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (cmp == 0) {
|
||||||
Py_DECREF(elem);
|
Py_DECREF(elem);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -362,12 +368,12 @@ _siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
|
||||||
while (pos > startpos){
|
while (pos > startpos){
|
||||||
parentpos = (pos - 1) >> 1;
|
parentpos = (pos - 1) >> 1;
|
||||||
parent = PyList_GET_ITEM(heap, parentpos);
|
parent = PyList_GET_ITEM(heap, parentpos);
|
||||||
cmp = PyObject_RichCompareBool(newitem, parent, Py_LE);
|
cmp = PyObject_RichCompareBool(parent, newitem, Py_LT);
|
||||||
if (cmp == -1) {
|
if (cmp == -1) {
|
||||||
Py_DECREF(newitem);
|
Py_DECREF(newitem);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (cmp == 1)
|
if (cmp == 0)
|
||||||
break;
|
break;
|
||||||
Py_INCREF(parent);
|
Py_INCREF(parent);
|
||||||
Py_DECREF(PyList_GET_ITEM(heap, pos));
|
Py_DECREF(PyList_GET_ITEM(heap, pos));
|
||||||
|
|
@ -403,14 +409,14 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos)
|
||||||
rightpos = childpos + 1;
|
rightpos = childpos + 1;
|
||||||
if (rightpos < endpos) {
|
if (rightpos < endpos) {
|
||||||
cmp = PyObject_RichCompareBool(
|
cmp = PyObject_RichCompareBool(
|
||||||
PyList_GET_ITEM(heap, childpos),
|
|
||||||
PyList_GET_ITEM(heap, rightpos),
|
PyList_GET_ITEM(heap, rightpos),
|
||||||
Py_LE);
|
PyList_GET_ITEM(heap, childpos),
|
||||||
|
Py_LT);
|
||||||
if (cmp == -1) {
|
if (cmp == -1) {
|
||||||
Py_DECREF(newitem);
|
Py_DECREF(newitem);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (cmp == 1)
|
if (cmp == 0)
|
||||||
childpos = rightpos;
|
childpos = rightpos;
|
||||||
}
|
}
|
||||||
/* Move the smaller child up. */
|
/* Move the smaller child up. */
|
||||||
|
|
@ -434,6 +440,7 @@ nsmallest(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem;
|
PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem;
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable))
|
if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -477,7 +484,12 @@ nsmallest(PyObject *self, PyObject *args)
|
||||||
else
|
else
|
||||||
goto sortit;
|
goto sortit;
|
||||||
}
|
}
|
||||||
if (PyObject_RichCompareBool(los, elem, Py_LE)) {
|
cmp = PyObject_RichCompareBool(elem, los, Py_LT);
|
||||||
|
if (cmp == -1) {
|
||||||
|
Py_DECREF(elem);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (cmp == 0) {
|
||||||
Py_DECREF(elem);
|
Py_DECREF(elem);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue