建立雙向隊列python
import collections d = collections.deque()
append(往右邊添加一個元素)linux
import collections d = collections.deque() d.append(1) d.append(2) print(d) #輸出:deque([1, 2])
appendleft(往左邊添加一個元素)shell
import collections d = collections.deque() d.append(1) d.appendleft(2) print(d) #輸出:deque([2, 1])
clear(清空隊列)數據結構
import collections d = collections.deque() d.append(1) d.clear() print(d) #輸出:deque([])
copy(淺拷貝)app
import collections d = collections.deque() d.append(1) new_d = d.copy() print(new_d) #輸出:deque([1])
count(返回指定元素的出現次數)post
import collections d = collections.deque() d.append(1) d.append(1) print(d.count(1)) #輸出:2
extend(從隊列右邊擴展一個列表的元素)this
import collections d = collections.deque() d.append(1) d.extend([3,4,5]) print(d) #輸出:deque([1, 3, 4, 5])
extendleft(從隊列左邊擴展一個列表的元素)url
import collections d = collections.deque() d.append(1) d.extendleft([3,4,5]) print(d) # # #輸出:deque([5, 4, 3, 1])
index(查找某個元素的索引位置)spa
import collections d = 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 collections d = collections.deque() d.extend(['a','b','c','d','e']) d.insert(2,'z') print(d) #輸出:deque(['a', 'b', 'z', 'c', 'd', 'e'])
pop(獲取最右邊一個元素,並在隊列中刪除)
import collections d = collections.deque() d.extend(['a','b','c','d','e']) x = d.pop() print(x,d) #輸出:e deque(['a', 'b', 'c', 'd'])
popleft(獲取最左邊一個元素,並在隊列中刪除)
import collections d = collections.deque() d.extend(['a','b','c','d','e']) x = d.popleft() print(x,d) #輸出:a deque(['b', 'c', 'd', 'e'])
remove(刪除指定元素)
import collections d = collections.deque() d.extend(['a','b','c','d','e']) d.remove('c') print(d) #輸出:deque(['a', 'b', 'd', 'e'])
reverse(隊列反轉)
import collections d = collections.deque() d.extend(['a','b','c','d','e']) d.reverse() print(d) #輸出:deque(['e', 'd', 'c', 'b', 'a'])
rotate(把右邊元素放到左邊)
import collections d = collections.deque() d.extend(['a','b','c','d','e']) d.rotate(2) #指定次數,默認1次 print(d) #輸出:deque(['d', 'e', 'a', 'b', 'c'])
queue模塊介紹
queue模塊定義了下面的類和異常:
class queue.Queue(maxsize=0)
import queue import time q = 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) 執行結果: 2 1 3
class queue.LifoQueue(maxsize=0)
import queue import time q = 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) 執行結果: 3 1 2
class queue.PriorityQueue(maxsize=0)
from queue import PriorityQueue import time q = 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
exception queue.Full
Queue對象(Queue、LifoQueue或者PriorityQueue)提供瞭如下方法:
Queue.qsize()
返回隊列的近似大小。注意,qsize() > 0並不能保證接下來的get()方法不被阻塞;一樣,qsize() < maxsize也不能保證put()將不被阻塞。import queue import time q = 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 queue q = 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 #隊列不爲空則返回False que is empty? :True #隊列未空則返回True
Queue.full()
若是隊列滿則返回True,不然返回False。若是full()返回True,並不能保證接下來的get()調用將不被阻塞。相似的,full()返回False也不能保證接下來的put()調用將不被阻塞。
import queue q = 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? :True que 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 queue import time q = 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.Full except queue.Full: print('queue is full!') print(time.ctime()) #打印當前時間,可看出q隊列阻塞時長 執行結果: Fri Nov 3 15:06:43 2017 queue is full! Fri Nov 3 15:06:46 2017
block爲False
import queue import time q = 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 queue import time q = queue.Queue(maxsize=2) #當前q隊列填爲空 print(time.ctime()) #打印當前時間 try: #捕獲queue.Empty異常 q.get(True, 5) #Queue.get()獲取數據阻塞5s except queue.Empty: print('queue is empty!') print(time.ctime()) #打印當前時間,可看出q隊列阻塞時長 執行結果:

block爲False
import queue import time q = 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 2017 queue 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 python3 import queue import time import subprocess import threading q = 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.68 host ip is:192.168.68.101 host ip is:192.168.66.250 host ip is:192.168.88.133 host ip is:192.168.88.118 Elapsed Time: 10.013836145401001 #因爲192.168.1.118大約阻塞了10S