web-dev-qa-db-fra.com

Quelle est la différence entre heapq et PriorityQueue en python?

Dans python il y a un algorithme heapq intégré qui vous donne Push, pop, nlargest, nsmallest... etc que vous pouvez appliquer aux listes. Cependant, il y a aussi le queue.PriorityQueue classe qui semble prendre en charge plus ou moins la même fonctionnalité. Quelle est la différence, et quand utiliseriez-vous l'un sur l'autre?

32
yelsayed

Queue.PriorityQueue est une classe thread-safe, tandis que le module heapq n'offre aucune garantie de thread-safety. Depuis la documentation du module Queue :

Le module Queue implémente des files d'attente multi-producteurs et multi-consommateurs. Il est particulièrement utile dans la programmation threadée lorsque les informations doivent être échangées en toute sécurité entre plusieurs threads. La classe Queue de ce module implémente toute la sémantique de verrouillage requise. Cela dépend de la disponibilité du support des threads en Python; voir le module threading.

Le module heapq n'offre aucun verrouillage et fonctionne sur les objets list standard, qui ne sont pas destinés à être thread-safe.

En fait, l'implémentation PriorityQueue utilise heapq sous le capot pour effectuer tous les travaux de priorisation, avec la base Queue classe fournissant le verrouillage pour rendre ce thread-safe. Voir code source pour plus de détails.

Cela rend le module heapq plus rapide; il n'y a pas de frais généraux de verrouillage. De plus, vous êtes libre d'utiliser les différentes fonctions heapq de différentes façons nouvelles, le PriorityQueue n'offre que la fonctionnalité de mise en file d'attente directe.

35
Martijn Pieters

queue.PriorityQueue Est un wrapper partiel autour de la classe heapq.

En d'autres termes, un queue.PriorityQueue Est en fait un heapq, placé dans le module de file d'attente avec quelques méthodes renommées pour rendre le heapq plus facile à utiliser, un peu comme une file d'attente régulière .

Dans heapq, vous utilisez la méthode heappush() pour ajouter un nouvel élément et la méthode heappop() pour en supprimer un. Ce n'est pas très semblable à une file d'attente, alors queue.PriorityQueue Vous permet d'utiliser les méthodes de file d'attente habituelles telles que Push et pop pour faire la même chose.

Certaines fonctionnalités de heapq ne sont pas transférées dans queue.PriorityQueue, Telles que heappushpop() et heapreplace(), mais vous êtes moins susceptible de les utiliser . Si vous en avez besoin (et je le fais dans mon projet actuel), vous devriez peut-être utiliser heapq plutôt que queue.PriorityQueue.

De plus, étant donné que heapq est spécialisé dans ce but, il n'est pas sûr pour les threads (comme indiqué dans une autre réponse ici.)

4
Rory Daulton