:mod:`heapq` --- Heap queue algorithm
=====================================

.. module:: heapq
   :synopsis: Heap queue algorithm (a.k.a. priority queue).

.. moduleauthor:: Kevin O'Connor
.. sectionauthor:: Guido van Rossum <guido@python.org>
.. sectionauthor:: François Pinard
.. sectionauthor:: Raymond Hettinger

**Source code:** :source:`Lib/heapq.py`

--------------

This module provides an implementation of the heap queue algorithm, also known
as the priority queue algorithm.

Heaps are binary trees for which every parent node has a value less than or
equal to any of its children.  This implementation uses arrays for which
``heap[k] <= heap[2*k+1]`` and ``heap[k] <= heap[2*k+2]`` for all *k*, counting
elements from zero.  For the sake of comparison, non-existing elements are
considered to be infinite.  The interesting property of a heap is that its
smallest element is always the root, ``heap[0]``.

The API below differs from textbook heap algorithms in two aspects: (a) We use
zero-based indexing.  This makes the relationship between the index for a node
and the indexes for its children slightly less obvious, but is more suitable
since Python uses zero-based indexing. (b) Our pop method returns the smallest
item, not the largest (called a "min heap" in textbooks; a "max heap" is more
common in texts because of its suitability for in-place sorting).

These two make it possible to view the heap as a regular Python list without
surprises: ``heap[0]`` is the smallest item, and ``heap.sort()`` maintains the
heap invariant!

To create a heap, use a list initialized to ``[]``, or you can transform a
populated list into a heap via function :func:`heapify`.

The following functions are provided:


.. function:: heappush(heap, item)

   Push the value *item* onto the *heap*, maintaining the heap invariant.


.. function:: heappop(heap)

   Pop and return the smallest item from the *heap*, maintaining the heap
   invariant.  If the heap is empty, :exc:`IndexError` is raised.  To access the
   smallest item without popping it, use ``heap[0]``.


.. function:: heappushpop(heap, item)

   Push *item* on the heap, then pop and return the smallest item from the
   *heap*.  The combined action runs more efficiently than :func:`heappush`
   followed by a separate call to :func:`heappop`.


.. function:: heapify(x)

   Transform list *x* into a heap, in-place, in linear time.


.. function:: heapreplace(heap, item)

   Pop and return the smallest item from the *heap*, and also push the new *item*.
   The heap size doesn't change. If the heap is empty, :exc:`IndexError` is raised.

   This one step operation is more efficient than a :func:`heappop` followed by
   :func:`heappush` and can be more appropriate when using a fixed-size heap.
   The pop/push combination always returns an element from the heap and replaces
   it with *item*.

   The value returned may be larger than the *item* added.  If that isn't
   desired, consider using :func:`heappushpop` instead.  Its push/pop
   combination returns the smaller of the two values, leaving the larger value
   on the heap.


The module also offers three general purpose functions based on heaps.


.. function:: merge(*iterables, key=None, reverse=False)

   Merge multiple sorted inputs into a single sorted output (for example, merge
   timestamped entries from multiple log files).  Returns an :term:`iterator`
   over the sorted values.

   Similar to ``sorted(itertools.chain(*iterables))`` but returns an iterable, does
   not pull the data into memory all at once, and assumes that each of the input
   streams is already sorted (smallest to largest).

   Has two optional arguments which must be specified as keyword arguments.

   *key* specifies a :term:`key function` of one argument that is used to
   extract a comparison key from each input element.  The default value is
   ``None`` (compare the elements directly).

   *reverse* is a boolean value.  If set to ``True``, then the input elements
   are merged as if each comparison were reversed. To achieve behavior similar
   to ``sorted(itertools.chain(*iterables), reverse=True)``, all iterables must
   be sorted from largest to smallest.

   .. versionchanged:: 3.5
      Added the optional *key* and *reverse* parameters.


.. function:: nlargest(n, iterable, key=None)

   Return a list with the *n* largest elements from the dataset defined by
   *iterable*.  *key*, if provided, specifies a function of one argument that is
   used to extract a comparison key from each element in the iterable:
   ``key=str.lower`` Equivalent to:  ``sorted(iterable, key=key,
   reverse=True)[:n]``


.. function:: nsmallest(n, iterable, key=None)

   Return a list with the *n* smallest elements from the dataset defined by
   *iterable*.  *key*, if provided, specifies a function of one argument that is
   used to extract a comparison key from each element in the iterable:
   ``key=str.lower`` Equivalent to:  ``sorted(iterable, key=key)[:n]``


The latter two functions perform best for smaller values of *n*.  For larger
values, it is more efficient to use the :func:`sorted` function.  Also, when
``n==1``, it is more efficient to use the built-in :func:`min` and :func:`max`
functions.  If repeated usage of these functions is required, consider turning
the iterable into an actual heap.


Basic Examples
--------------

A `heapsort <https://en.wikipedia.org/wiki/Heapsort>`_ can be implemented by
pushing all values onto a heap and then popping off the smallest values one at a
time::

   >>> def heapsort(iterable):
   ...     h = []
   ...     for value in iterable:
   ...         heappush(h, value)
   ...     return [heappop(h) for i in range(len(h))]
   ...
   >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

This is similar to ``sorted(iterable)``, but unlike :func:`sorted`, this
implementation is not stable.

Heap elements can be tuples.  This is useful for assigning comparison values
(such as task priorities) alongside the main record being tracked::

    >>> h = []
    >>> heappush(h, (5, 'write code'))
    >>> heappush(h, (7, 'release product'))
    >>> heappush(h, (1, 'write spec'))
    >>> heappush(h, (3, 'create tests'))
    >>> heappop(h)
    (1, 'write spec')


Priority Queue Implementation Notes
-----------------------------------

A `priority queue <https://en.wikipedia.org/wiki/Priority_queue>`_ is common use
for a heap, and it presents several implementation challenges:

* Sort stability:  how do you get two tasks with equal priorities to be returned
  in the order they were originally added?

* Tuple comparison breaks for (priority, task) pairs if the priorities are equal
  and the tasks do not have a default comparison order.

* If the priority of a task changes, how do you move it to a new position in
  the heap?

* Or if a pending task needs to be deleted, how do you find it and remove it
  from the queue?

A solution to the first two challenges is to store entries as 3-element list
including the priority, an entry count, and the task.  The entry count serves as
a tie-breaker so that two tasks with the same priority are returned in the order
they were added. And since no two entry counts are the same, the tuple
comparison will never attempt to directly compare two tasks.

Another solution to the problem of non-comparable tasks is to create a wrapper
class that ignores the task item and only compares the priority field::

    from dataclasses import dataclass, field
    from typing import Any

    @dataclass(order=True)
    class PrioritizedItem:
        priority: int
        item: Any=field(compare=False)

The remaining challenges revolve around finding a pending task and making
changes to its priority or removing it entirely.  Finding a task can be done
with a dictionary pointing to an entry in the queue.

Removing the entry or changing its priority is more difficult because it would
break the heap structure invariants.  So, a possible solution is to mark the
entry as removed and add a new entry with the revised priority::

    pq = []                         # list of entries arranged in a heap
    entry_finder = {}               # mapping of tasks to entries
    REMOVED = '<removed-task>'      # placeholder for a removed task
    counter = itertools.count()     # unique sequence count

    def add_task(task, priority=0):
        'Add a new task or update the priority of an existing task'
        if task in entry_finder:
            remove_task(task)
        count = next(counter)
        entry = [priority, count, task]
        entry_finder[task] = entry
        heappush(pq, entry)

    def remove_task(task):
        'Mark an existing task as REMOVED.  Raise KeyError if not found.'
        entry = entry_finder.pop(task)
        entry[-1] = REMOVED

    def pop_task():
        'Remove and return the lowest priority task. Raise KeyError if empty.'
        while pq:
            priority, count, task = heappop(pq)
            if task is not REMOVED:
                del entry_finder[task]
                return task
        raise KeyError('pop from an empty priority queue')


Theory
------

Heaps are arrays for which ``a[k] <= a[2*k+1]`` and ``a[k] <= a[2*k+2]`` for all
*k*, counting elements from 0.  For the sake of comparison, non-existing
elements are considered to be infinite.  The interesting property of a heap is
that ``a[0]`` is always its smallest element.

The strange invariant above is meant to be an efficient memory representation
for a tournament.  The numbers below are *k*, not ``a[k]``::

                                  0

                 1                                 2

         3               4                5               6

     7       8       9       10      11      12      13      14

   15 16   17 18   19 20   21 22   23 24   25 26   27 28   29 30

In the tree above, each cell *k* is topping ``2*k+1`` and ``2*k+2``. In a usual
binary tournament we see in sports, each cell is the winner over the two cells
it tops, and we can trace the winner down the tree to see all opponents s/he
had.  However, in many computer applications of such tournaments, we do not need
to trace the history of a winner. To be more memory efficient, when a winner is
promoted, we try to replace it by something else at a lower level, and the rule
becomes that a cell and the two cells it tops contain three different items, but
the top cell "wins" over the two topped cells.

If this heap invariant is protected at all time, index 0 is clearly the overall
winner.  The simplest algorithmic way to remove it and find the "next" winner is
to move some loser (let's say cell 30 in the diagram above) into the 0 position,
and then percolate this new 0 down the tree, exchanging values, until the
invariant is re-established. This is clearly logarithmic on the total number of
items in the tree. By iterating over all items, you get an O(n log n) sort.

A nice feature of this sort is that you can efficiently insert new items while
the sort is going on, provided that the inserted items are not "better" than the
last 0'th element you extracted.  This is especially useful in simulation
contexts, where the tree holds all incoming events, and the "win" condition
means the smallest scheduled time.  When an event schedules other events for
execution, they are scheduled into the future, so they can easily go into the
heap.  So, a heap is a good structure for implementing schedulers (this is what
I used for my MIDI sequencer :-).

Various structures for implementing schedulers have been extensively studied,
and heaps are good for this, as they are reasonably speedy, the speed is almost
constant, and the worst case is not much different than the average case.
However, there are other representations which are more efficient overall, yet
the worst cases might be terrible.

Heaps are also very useful in big disk sorts.  You most probably all know that a
big sort implies producing "runs" (which are pre-sorted sequences, whose size is
usually related to the amount of CPU memory), followed by a merging passes for
these runs, which merging is often very cleverly organised [#]_. It is very
important that the initial sort produces the longest runs possible.  Tournaments
are a good way to achieve that.  If, using all the memory available to hold a
tournament, you replace and percolate items that happen to fit the current run,
you'll produce runs which are twice the size of the memory for random input, and
much better for input fuzzily ordered.

Moreover, if you output the 0'th item on disk and get an input which may not fit
in the current tournament (because the value "wins" over the last output value),
it cannot fit in the heap, so the size of the heap decreases.  The freed memory
could be cleverly reused immediately for progressively building a second heap,
which grows at exactly the same rate the first heap is melting.  When the first
heap completely vanishes, you switch heaps and start a new run.  Clever and
quite effective!

In a word, heaps are useful memory structures to know.  I use them in a few
applications, and I think it is good to keep a 'heap' module around. :-)

.. rubric:: Footnotes

.. [#] The disk balancing algorithms which are current, nowadays, are more annoying
   than clever, and this is a consequence of the seeking capabilities of the disks.
   On devices which cannot seek, like big tape drives, the story was quite
   different, and one had to be very clever to ensure (far in advance) that each
   tape movement will be the most effective possible (that is, will best
   participate at "progressing" the merge).  Some tapes were even able to read
   backwards, and this was also used to avoid the rewinding time. Believe me, real
   good tape sorts were quite spectacular to watch! From all times, sorting has
   always been a Great Art! :-)

