In Python gibt es einen eingebauten heapq
Algorithmus, der Ihnen push
, pop
, nlargest
, nsmallest
... usw. gibt, die Sie auf Listen anwenden können. Allerdings gibt es auch die queue.PriorityQueue
Klasse, die mehr oder weniger die gleiche Funktionalität zu unterstützen scheint. Was ist der Unterschied, und wann würdest du eins über dem anderen benutzen?Was ist der Unterschied zwischen heapq und PriorityQueue in Python?
Antwort
Queue.PriorityQueue
ist eine Thread-sichere Klasse, während das heapq
Modul keine Thread-Sicherheit garantiert. Von den Queue
module documentation:
Das
Queue
Modul implementiert Multi-Produzenten, Multi-Verbraucher-Warteschlangen. Es ist besonders nützlich in der Thread-Programmierung, wenn Informationen sicher zwischen mehreren Threads ausgetauscht werden müssen. Die KlasseQueue
in diesem Modul implementiert alle erforderlichen Sperrsemantiken. Dies hängt von der Verfügbarkeit der Thread-Unterstützung in Python ab. siehe dasthreading
Modul.
heapq
Das Modul bietet keine Verriegelung und arbeitet auf Standard list
Objekte, die nicht dazu gedacht sind threadsicher zu sein.
In der Tat, die PriorityQueue
Umsetzung verwendet heapq
unter der Haube all Priorisierungs Arbeit zu tun, wobei die Basis Queue
Klasse der Verriegelungs Bereitstellung diesen threadsicher zu machen. Details finden Sie unter source code.
Dies macht das Modul heapq
schneller; Es gibt keinen Sperraufwand. Darüber hinaus steht es Ihnen frei, die verschiedenen heapq
Funktionen auf verschiedene, neue Arten zu verwenden, die PriorityQueue
bietet nur die geradlinige Warteschlangenfunktionalität.
queue.PriorityQueue ist ein partieller Wrapper um die heapq-Klasse.
Mit anderen Worten, eine queue.PriorityQueue ist eigentlich ein heapq, der mit ein paar umbenannten Methoden in das Queue-Modul gestellt wird, um den heapq einfacher zu benutzen, ähnlich einer regulären Queue.
Verwenden Sie in heapq die Methode heappush(), um ein neues Element hinzuzufügen, und die Methode heappop(), um eins zu entfernen. Das ist nicht sehr queue-ähnlich, so dass Sie mit queue.PriorityQueue die üblichen Queue-Methoden wie Push und Pop verwenden können, um das Gleiche zu tun.
Es gibt einige Funktionen von heapq, die nicht in queue.PriorityQueue, wie heappushpop() und heappreplace() übertragen werden, aber Sie sind weniger gerne diese zu verwenden. Wenn Sie sie brauchen (und ich in meinem aktuellen Projekt), verwenden Sie heapq statt queue.PriorityQueue.
Auch, da Heapq für seinen Zweck spezialisiert ist, ist es nicht Thread-sicher (wie in einer anderen Antwort hier erwähnt).