web-dev-qa-db-ja.com

PythonのheapqとPriorityQueueの違いは何ですか?

pythonでは、heapqPushpopnlargest...などを提供する組み込みのnsmallestアルゴリズムがあります。ただし、リストに適用できます。ただし、queue.PriorityQueueほぼ同じ機能をサポートしていると思われるクラス。違いは何ですか?また、いつ使用するのですか?

32
yelsayed

Queue.PriorityQueueはスレッドセーフクラスですが、heapqモジュールはスレッドセーフを保証しません。 Queue module documentation から:

Queueモジュールは、マルチプロデューサー、マルチコンシューマーのキューを実装します。複数のスレッド間で情報を安全に交換する必要があるスレッドプログラミングで特に役立ちます。このモジュールのQueueクラスは、必要なロックセマンティクスをすべて実装しています。 Pythonでのスレッドサポートの可用性に依存します。 threadingモジュールを参照してください。

heapqモジュールはロックを提供せず、スレッドセーフではない標準のlistオブジェクトで動作します。

実際、PriorityQueueimplementationは、フードの下でheapqを使用してすべての優先順位付け作業を行い、ベースのQueueクラスがこのスレッドセーフにするロックを提供します。詳細については ソースコード をご覧ください。

これにより、heapqモジュールが高速になります。ロックのオーバーヘッドはありません。さらに、さまざまなheapq関数をさまざまな新しい方法で自由に使用できます。PriorityQueueはストレートキューイング機能のみを提供します。

35
Martijn Pieters

_queue.PriorityQueue_は、heapqクラスの部分的なラッパーです。

つまり、_queue.PriorityQueue_は実際にはheapqであり、通常のキューと同様に、heapqを使いやすくするためにいくつかの名前が変更されたメソッドとともにキューモジュールに配置されます。

heapqでは、メソッドheappush()を使用して新しいアイテムを追加し、メソッドheappop()を使用してアイテムを削除します。それはあまりキューに似ていないので、_queue.PriorityQueue_を使用すると、Pushpopなどの通常のキューメソッドを使用して同じことを行うことができます。

heapqには、heappushpop()heapreplace()など、_queue.PriorityQueue_に引き継がれない機能がいくつかありますが、これらを使用する可能性は低くなります。それらが必要な場合(そして現在のプロジェクトで必要です)、おそらく_queue.PriorityQueue_ではなくheapqを使用する必要があります。

また、heapqはその目的に特化されているため、スレッドセーフではありません(別の回答に記載されています)。

4
Rory Daulton