2016-05-02 5 views
14

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

18

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 Klasse Queue in diesem Modul implementiert alle erforderlichen Sperrsemantiken. Dies hängt von der Verfügbarkeit der Thread-Unterstützung in Python ab. siehe das threading 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 PriorityQueueUmsetzung 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.

1

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).