上一篇文章: Python實用技法第3篇:找到最大或最小的N個元素
下一篇文章: Python實用技法第5篇:一鍵多值字典
咱們想要實現一個隊列,它可以以給定的優先級來對元素排序,且每次pop操做時都會返回優先級最高的那個元素
利用heapq模塊實現
代碼:segmentfault
import heapq #利用heapq實現一個簡答的優先級隊列 class PriorityQueue: def __init__(self): self._queue=[] self._index=0 def push(self,item,priority): heapq.heappush(self._queue,(-priority,self._index,item)) self._index+=1 def pop(self): return heapq.heappop(self._queue)[-1] class Item: def __init__(self,name): self.name=name def __repr__(self): return 'Item({!r})'.format(self.name) if __name__ == '__main__': q=PriorityQueue() q.push(Item('foo'),1) q.push(Item('bar'),5) q.push(Item('spam'),4) q.push(Item('grok'),1) print(q.pop()) print(q.pop()) #具備相同優先級的兩個元素,返回的順序同它們插入到隊列時的順序相同 print(q.pop()) print(q.pop())
運行結果:app
Item('bar') Item('spam') Item('foo') Item('grok')
上面的代碼核心在於heapq模塊的使用。函數heapq.heapqpush()以及heapq.heapqpop()分別實現將元素從列表_queue中插入和移除,且保證列表中第一個元素的優先級最低。heappop()方法老是返回【最小】的元素,所以這就是讓隊列能彈出正確元素的關鍵。此外,因爲push和pop操做的複雜度都是O(logN),其中N表明堆中元素的數量,所以就算N的值很大,這些操做的效率也很是高。上面代碼中,隊列以元組(-priority ,index,item)的形式組成。把priority取負值是爲了讓隊列可以按照元素的優先級從高到底的順序排列。函數
變量index的做用是爲了將具備相同優先級的元素以適當的順序排列。經過維護一個不斷遞增的索引,元素將以它們如隊列時的順序來排列。爲了說明index的做用,看下面實例:spa
代碼:code
class Item: def __init__(self,name): self.name=name def __repr__(self): return 'Item({!r})'.format(self.name) if __name__ == '__main__': a=(1,Item('foo')) b=(5,Item('bar')) #下面一句打印True print(a<b) c=(1,Item('grok')) #下面一句會報錯:TypeError: '<' not supported between instances of 'Item' and 'Item' print(c<a) d=(1,0,Item('foo')) e=(5,1,Item('bar')) f=(1,2,Item('grok')) #下面一句打印True print(d<e) #下面一句打印True print(d<f)
上一篇文章: Python實用技法第3篇:找到最大或最小的N個元素
下一篇文章: Python實用技法第5篇:一鍵多值字典