Skip to content

Commit 484793a

Browse files
gh-110067: Improve max-heap documentation across heapq module
- Add max-heap usage examples to module docstrings in both the Python (Lib/heapq.py) and C (Modules/_heapqmodule.c) implementations - Add descending heapsort example using max-heap functions to Doc/library/heapq.rst - Expand the What's New in 3.14 entry for heapq with descriptions of each new max-heap function, context about the change, and correct contributor attribution
1 parent 52c0186 commit 484793a

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

Doc/library/heapq.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,18 @@ time::
214214
This is similar to ``sorted(iterable)``, but unlike :func:`sorted`, this
215215
implementation is not stable.
216216

217+
Using max-heap functions, a reverse (descending) heapsort is equally
218+
straightforward::
219+
220+
>>> def heapsort_desc(iterable):
221+
... h = []
222+
... for value in iterable:
223+
... heappush_max(h, value)
224+
... return [heappop_max(h) for i in range(len(h))]
225+
...
226+
>>> heapsort_desc([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
227+
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
228+
217229
Heap elements can be tuples. This is useful for assigning comparison values
218230
(such as task priorities) alongside the main record being tracked::
219231

Doc/whatsnew/3.14.rst

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,14 +1387,19 @@ graphlib
13871387
heapq
13881388
-----
13891389

1390-
* The :mod:`!heapq` module has improved support for working with max-heaps,
1391-
via the following new functions:
1392-
1393-
* :func:`~heapq.heapify_max`
1394-
* :func:`~heapq.heappush_max`
1395-
* :func:`~heapq.heappop_max`
1396-
* :func:`~heapq.heapreplace_max`
1397-
* :func:`~heapq.heappushpop_max`
1390+
* The :mod:`!heapq` module now has full public support for max-heaps,
1391+
providing a symmetric API to the existing min-heap functions.
1392+
Max-heaps maintain the reverse invariant: ``heap[0]`` is always the
1393+
*largest* element. The new functions are:
1394+
1395+
* :func:`~heapq.heapify_max`: Transform a list into a max-heap in-place
1396+
* :func:`~heapq.heappush_max`: Push an item onto a max-heap
1397+
* :func:`~heapq.heappop_max`: Pop the largest item from a max-heap
1398+
* :func:`~heapq.heapreplace_max`: Pop largest and push new item in one step
1399+
* :func:`~heapq.heappushpop_max`: Push new item and pop largest in one step
1400+
1401+
These were previously available only as undocumented internal helpers.
1402+
(Contributed by Stan Ulbrych in :gh:`110067`.)
13981403

13991404

14001405
hmac

Lib/heapq.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
non-existing elements are considered to be infinite. The interesting
66
property of a heap is that a[0] is always its smallest element.
77
8-
Usage:
8+
Usage (min-heap):
99
1010
heap = [] # creates an empty heap
1111
heappush(heap, item) # pushes a new item on the heap
@@ -17,6 +17,18 @@
1717
item = heapreplace(heap, item) # pops and returns smallest item, and adds
1818
# new item; the heap size is unchanged
1919
20+
Usage (max-heap):
21+
22+
heap = [] # creates an empty max-heap
23+
heappush_max(heap, item) # pushes a new item on the max-heap
24+
item = heappop_max(heap) # pops the largest item from the max-heap
25+
item = heap[0] # largest item on the max-heap without popping it
26+
heapify_max(x) # transforms list into a max-heap, in-place, in linear time
27+
item = heappushpop_max(heap, item) # pushes a new item and then returns
28+
# the largest item; the heap size is unchanged
29+
item = heapreplace_max(heap, item) # pops and returns largest item, and adds
30+
# new item; the heap size is unchanged
31+
2032
Our API differs from textbook heap algorithms as follows:
2133
2234
- We use 0-based indexing. This makes the relationship between the

Modules/_heapqmodule.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ all k, counting elements from 0. For the sake of comparison,\n\
658658
non-existing elements are considered to be infinite. The interesting\n\
659659
property of a heap is that a[0] is always its smallest element.\n\
660660
\n\
661-
Usage:\n\
661+
Usage (min-heap):\n\
662662
\n\
663663
heap = [] # creates an empty heap\n\
664664
heappush(heap, item) # pushes a new item on the heap\n\
@@ -668,6 +668,16 @@ heapify(x) # transforms list into a heap, in-place, in linear time\n\
668668
item = heapreplace(heap, item) # pops and returns smallest item, and adds\n\
669669
# new item; the heap size is unchanged\n\
670670
\n\
671+
Usage (max-heap):\n\
672+
\n\
673+
heap = [] # creates an empty max-heap\n\
674+
heappush_max(heap, item) # pushes a new item on the max-heap\n\
675+
item = heappop_max(heap) # pops the largest item from the max-heap\n\
676+
item = heap[0] # largest item on the max-heap without popping it\n\
677+
heapify_max(x) # transforms list into a max-heap, in-place, in linear time\n\
678+
item = heapreplace_max(heap, item) # pops and returns largest item, and adds\n\
679+
# new item; the heap size is unchanged\n\
680+
\n\
671681
Our API differs from textbook heap algorithms as follows:\n\
672682
\n\
673683
- We use 0-based indexing. This makes the relationship between the\n\

0 commit comments

Comments
 (0)