標籤:二叉樹 except 指定 不能 port pre 完成 拋出異常 最小
建立雙向隊列
import collectionsd = collections.deque()
append(往右邊添加一個元素)
import collectionsd = collections.deque()d.append(1)d.append(2)print(d)#輸出:deque([1, 2])
appendleft(往左邊添加一個元素)
import collectionsd = collections.deque()d.append(1)d.appendleft(2)print(d)#輸出:deque([2, 1])
clear(清空隊列)
import collectionsd = collections.deque()d.append(1)d.clear()print(d)#輸出:deque([])
copy(淺拷貝)
import collectionsd = collections.deque()d.append(1)new_d = d.copy()print(new_d)#輸出:deque([1])
count(返回指定元素的出現次數)
import collectionsd = collections.deque()d.append(1)d.append(1)print(d.count(1))#輸出:2
extend(從隊列右邊擴充一個列表的元素)
import collectionsd = collections.deque()d.append(1)d.extend([3,4,5])print(d)#輸出:deque([1, 3, 4, 5])
extendleft(從隊列左邊擴充一個列表的元素)
import collectionsd = collections.deque()d.append(1)d.extendleft([3,4,5])print(d)## #輸出:deque([5, 4, 3, 1])
index(尋找某個元素的索引位置)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])print(d)print(d.index(‘e‘))print(d.index(‘c‘,0,3)) #指定尋找區間#輸出:deque([‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘])# 4# 2
insert(在指定位置插入元素)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])d.insert(2,‘z‘)print(d)#輸出:deque([‘a‘, ‘b‘, ‘z‘, ‘c‘, ‘d‘, ‘e‘])
pop(擷取最右邊一個元素,並在隊列中刪除)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])x = d.pop()print(x,d)#輸出:e deque([‘a‘, ‘b‘, ‘c‘, ‘d‘])
popleft(擷取最左邊一個元素,並在隊列中刪除)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])x = d.popleft()print(x,d)#輸出:a deque([‘b‘, ‘c‘, ‘d‘, ‘e‘])
remove(刪除指定元素)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])d.remove(‘c‘)print(d)#輸出:deque([‘a‘, ‘b‘, ‘d‘, ‘e‘])
reverse(隊列反轉)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])d.reverse()print(d)#輸出:deque([‘e‘, ‘d‘, ‘c‘, ‘b‘, ‘a‘])
rotate(把右邊元素放到左邊)
import collectionsd = collections.deque()d.extend([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘])d.rotate(2) #指定次數,預設1次print(d)#輸出:deque([‘d‘, ‘e‘, ‘a‘, ‘b‘, ‘c‘])
queue模組介紹模組實現了3種類型的隊列,區別在於隊列中條目檢索的順序不同。在FIFO隊列中,按照先進先出的順序檢索條目。在LIFO隊列中,最後添加的條目最先檢索到(操作類似一個棧)。在優先順序隊列中,條目被儲存為有序的(使用heapq模組)並且最小值的條目被最先檢索。queue模組定義了下面的類和異常:class queue.Queue(maxsize=0)FIFO隊列的構造器。maxsize為一個整數,表示隊列的最大條目數。一旦隊列滿,插入將被阻塞直到隊列中存在空閑空間。如果maxsize小於等於0,隊列大小為無限。maxsize預設為0
import queueimport timeq = queue.Queue()#FIFO隊列先進先出q.put(2)q.put(1)q.put(3)while not q.empty(): next_item = q.get() print(next_item) time.sleep(1)執行結果:213
class queue.LifoQueue(maxsize=0)LIFO隊列的構造器。maxsize是一個整數,表示隊列的最大條目數。一旦隊列滿,插入將被阻塞直到隊列中存在空閑空間。如果maxsize小於等於0,隊列大小為無限。maxsize預設為0
import queueimport timeq = queue.LifoQueue()#LIFO隊列後進先出q.put(2)q.put(1)q.put(3)while not q.empty(): next_item = q.get() print(next_item) time.sleep(1)執行結果:312
class queue.PriorityQueue(maxsize=0)優先隊列,有別於普通隊列的先入先出(雖然字面上還是隊列,但其實無論從含義還是實現上,和普通隊列都有很大的區別),也有別於棧的先入後出。在實現上,它一般通過堆這一資料結構,而堆其實是一種完全二叉樹,它會對進入容器的元素進行排序(根據事先指定的規則),出隊的順序則會是二叉樹的根結點代表的元素。
from queue import PriorityQueueimport timeq = PriorityQueue()q.put((2, ‘code‘))q.put((1, ‘eat‘))q.put((3, ‘sleep‘))while not q.empty(): next_item = q.get() print(next_item) time.sleep(3)執行結果:(1, ‘eat‘)(2, ‘code‘)(3, ‘sleep‘)
exception queue.Empty當Queue為空白時,非阻塞的get()或者get_nowait()被調用時,將拋出該異常。exception queue.Full當隊列滿時,非阻塞的put()或者put_nowait()被調用,將拋出該異常。Queue對象(Queue、LifoQueue或者PriorityQueue)提供了以下方法:
Queue.qsize()返回隊列的近似大小。注意,qsize() > 0並不能保證接下來的get()方法不被阻塞;同樣,qsize() < maxsize也不能保證put()將不被阻塞。
import queueimport timeq = queue.Queue()q.put(2)q.put(1)q.put(3)q.put(‘python‘)print(‘queue long:%s‘%q.qsize())執行結果:queue long:4
Queue.empty()
如果隊列是空的,則返回True,否則False。如果empty()返回True,並不能保證接下來的put()調用將不被阻塞。類似的,empty()返回False也不能保證接下來的get()調用將不被阻塞。
import queueq = queue.Queue()que = queue.Queue()q.put(2)q.put(1)q.put(3)q.put(‘python‘)print(‘q is empty? :%s‘%q.empty())print(‘que is empty? :%s‘%que.empty())執行結果:q is empty? :False #隊列不為空白則返回Falseque is empty? :True #隊列未空則返回True
Queue.full()
如果隊列滿則返回True,否則返回False。如果full()返回True,並不能保證接下來的get()調用將不被阻塞。類似的,full()返回False也不能保證接下來的put()調用將不被阻塞。
import queueq = queue.Queue(maxsize=4)que = queue.Queue()q.put(2)q.put(1)q.put(3)q.put(‘python‘)print(‘q is full? :%s‘%q.full())print(‘que is full? :%s‘%que.full())執行結果:q is full? :Trueque is full? :False
Queue.put(item, block=True, timeout=None)
放item到隊列中。如果block是True,且timeout是None,該方法將一直等待直到有隊列有空餘空間(預設block=True,timeout=None)。如果timeout是一個正整數,該方法則最多阻塞timeout秒並拋出Full異常。如果block是False並且隊列滿,則直接拋出Full異常(這時timeout將被忽略)。
block為True
import queueimport timeq = queue.Queue(maxsize=2)#將q隊列填滿q.put(‘python‘)q.put(‘linux‘)print(time.ctime()) #列印目前時間try: #捕獲queue.Full異常 #q.put(‘shell‘, timeout=3) #預設block=True #q.put(‘shell‘, True, timeout=3) #可以省略block=;直接寫True;timeout=可以省略直接寫3 q.put(‘shell‘, block=True, timeout=3) #q隊列已滿,再次將資料放入q中,將阻塞3s後拋出異常queue.Fullexcept queue.Full: print(‘queue is full!‘) print(time.ctime()) #列印目前時間,可看出q隊列阻塞時間長度執行結果:Fri Nov 3 15:06:43 2017queue is full!Fri Nov 3 15:06:46 2017
block為False
import queueimport timeq = queue.Queue(maxsize=2)#將q隊列填滿q.put(‘python‘)q.put(‘linux‘)print(time.ctime()) #列印目前時間try: #捕獲queue.Full異常 q.put(‘shell‘, False, timeout=3) #block為False時,timeout失效會立即拋出queue.Full異常;故timeout選項可以省略不寫except queue.Full: print(‘queue is full!‘) print(time.ctime()) #列印目前時間,可看出q隊列阻塞時間長度執行結果:
Queue.put_nowait(item)
等價於put(item, False)。
Queue.get(block=True, timeout=None)
從隊列中移除被返回一個條目。如果block是True並且timeout是None(預設block=True,timeout=None),該方法將阻塞直到隊列中有條目可用。如果timeout是正整數,該方法將最多阻塞timeout秒並拋出Empty異常。如果block是False並且隊列為空白,則直接拋出Empty異常(這時timeout將被忽略)。
block為True
import queueimport timeq = queue.Queue(maxsize=2)#當前q隊列填為空白print(time.ctime()) #列印目前時間try: #捕獲queue.Empty異常 q.get(True, 5) #Queue.get()擷取資料阻塞5sexcept queue.Empty: print(‘queue is empty!‘) print(time.ctime()) #列印目前時間,可看出q隊列阻塞時間長度執行結果:
block為False
import queueimport timeq = queue.Queue(maxsize=2)#當前q隊列填為空白print(time.ctime()) #列印目前時間try: #捕獲queue.Empty異常 #q.get(False, 5) #Queue.get()擷取資料阻塞5s,block=/timeout=可以省略;block=False時timeout可以省略 q.get(False)except queue.Empty: print(‘queue is empty!‘) print(time.ctime()) #列印目前時間,可看出q隊列阻塞時間長度執行結果:Fri Nov 3 15:38:23 2017queue is empty!Fri Nov 3 15:38:23 2017
Queue.get_nowait()
等價於get(False)。
Queue.task_done()
表示一個先前的隊列中的任務完成了。被隊列消費者線程使用。對於每個get()擷取到的任務,接下來的task_done()的調用告訴隊列該任務的處理已經完成。
如果join()調用正在阻塞,當隊列中所有的條目被處理後它將恢複執行(意味著task_done()調用將被放入隊列中的每個條目接收到)。
如果調用次數超過了隊列中放置的條目數目,將拋出ValueError異常。
Queue.join() 阻塞直到隊列中所有條目都被擷取並處理。
當一個條目被增加到隊列時,未完成任務的計數將增加。當一個消費者線程調用task_done()時,未完成任務的計數將減少。當未完成任務的計數減少到0時,join()解鎖。
#!/usr/bin/env python3import queueimport timeimport subprocessimport threadingq = queue.Queue()hosts = [‘192.168.1.68‘, ‘192.168.1.118‘, ‘192.168.1.101‘, ‘192.168.1.250‘, ‘192.168.1.133‘]def run(): while True: #防止線程少於len(hosts)時卡死,不用while迴圈線程數少時就會導致隊列資料無法全部取完,就會造成queue.join()一直阻塞狀態 host = q.get() if host == ‘192.168.1.118‘: #如果ip等於192.168.1.118就休眠10S,用於判讀queue.join()是否阻塞直到queue.task_doen()通知後接觸阻塞 time.sleep(10) print(‘host ip is:%s‘% host) q.task_done() #當前線程任務完成def main(): for i in range(10): t = threading.Thread(target=run) t.setDaemon(True) t.start() for item in hosts: q.put(item) q.join() #阻塞直至所有線程queue.task_done()返回 start = time.time()main()print("Elapsed Time: %s" % (time.time() - start))執行結果:host ip is:192.168.88.68host ip is:192.168.68.101host ip is:192.168.66.250host ip is:192.168.88.133host ip is:192.168.88.118Elapsed Time: 10.013836145401001 #由於192.168.1.118大約阻塞了10S
python 中的queue, deque