This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add heapremove() function to heapq
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.8
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: Wanja Chresta, tim.peters
Priority: normal Keywords:

Created on 2019-01-04 23:40 by Wanja Chresta, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg333024 - (view) Author: Wanja Chresta (Wanja Chresta) Date: 2019-01-04 23:40
Heap Queues are extremely useful data structures. They can, for example, be used to implement Dijkstra's algorithm for finding the shortest paths between nodes in a graph in O(edge * log vertices) time instead of (edge * vertices) without heaps.

One operation such implementations need, though, is the possibility to modify an element in the heap (and thus having to reorder it afterwards) in O(log n) time. One can model such an operation by removing a specific element from the heap and then adding the modified element.

So far, heapq only allows removing the first element through heappop; this is not what we need. Instead, we would want to support a heapremove function that removes an arbitrary element in the heap (if it exists) and raises ValueError if the value is not present.

list.remove cannot be used, since it needs O(n) time.

heapremove can be easily implemented by using bisect.bisect_left since heap is always sorted:

def heapremove(heap, x):
  i = bisect.bisect_left(heap, x)
  if heap[i] == x:
    del heap[i]
  else:
    raise ValueError

c.f. remove method in https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
msg333027 - (view) Author: Wanja Chresta (Wanja Chresta) Date: 2019-01-04 23:59
After thinking about it some more I realised that this doesn't make sense since heapq is based on lists and lists have an insertion complexity of O(n). Thus, they'll never read the needed O(log n) and heapq is the wrong place.

Never mind.
msg333029 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2019-01-05 00:50
For history, note that `bisect` doesn't always work in this context either:  a heap is NOT always in sorted order.  For example, this is "a (min) heap" too:  [1, 3, 2].

More, that's "the real" problem.  If we could find the element to be removed in log(n) time, then it's possible to remove it from the heap in log(n) time too (you can, e.g., bubble elements up to fill the interior hole, then move the last heap element into the leaf hole that may leave behind and possibly sift it up to restore the heap property; and each of those phases takes log(n) time).
History
Date User Action Args
2022-04-11 14:59:09adminsetgithub: 79840
2019-01-05 00:50:25tim.peterssetnosy: + tim.peters
messages: + msg333029
2019-01-04 23:59:01Wanja Chrestasetstatus: open -> closed
resolution: wont fix
messages: + msg333027

stage: resolved
2019-01-04 23:41:51Wanja Chrestasettype: enhancement
2019-01-04 23:40:05Wanja Chrestacreate