zoukankan      html  css  js  c++  java
  • python 中的queue, deque

    python3 deque(双向队列)

    创建双向队列

    import collections
    d = collections.deque()

    append(往右边添加一个元素)

    复制代码
    import collections
    d = collections.deque()
    d.append(1)
    d.append(2)
    print(d)
    
    #输出:deque([1, 2])
    复制代码

    appendleft(往左边添加一个元素)

    复制代码
    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(浅拷贝)

    复制代码
    import collections
    d = collections.deque()
    d.append(1)
    new_d = d.copy()
    print(new_d)
    
    #输出:deque([1])
    复制代码

    count(返回指定元素的出现次数)

    复制代码
    import collections
    d = collections.deque()
    d.append(1)
    d.append(1)
    print(d.count(1))
    
    #输出:2
    复制代码

    extend(从队列右边扩展一个列表的元素)

    复制代码
    import collections
    d = collections.deque()
    d.append(1)
    d.extend([3,4,5])
    print(d)
    
    #输出:deque([1, 3, 4, 5])
    复制代码

    extendleft(从队列左边扩展一个列表的元素)

    复制代码
    import collections
    d = collections.deque()
    d.append(1)
    d.extendleft([3,4,5])
    print(d)
    #
    # #输出:deque([5, 4, 3, 1])
    复制代码

    index(查找某个元素的索引位置)

    复制代码
    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模块介绍

    模块实现了3种类型的队列,区别在于队列中条目检索的顺序不同。在FIFO队列中,按照先进先出的顺序检索条目。在LIFO队列中,最后添加的条目最先检索到(操作类似一个栈)。在优先级队列中,条目被保存为有序的(使用heapq模块)并且最小值的条目被最先检索。

    queue模块定义了下面的类和异常:

    class queue.Queue(maxsize=0)

    FIFO队列的构造器。maxsize为一个整数,表示队列的最大条目数。一旦队列满,插入将被阻塞直到队列中存在空闲空间。如果maxsize小于等于0,队列大小为无限。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)

    LIFO队列的构造器。maxsize是一个整数,表示队列的最大条目数。一旦队列满,插入将被阻塞直到队列中存在空闲空间。如果maxsize小于等于0,队列大小为无限。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

    当Queue为空时,非阻塞的get()或者get_nowait()被调用时,将抛出该异常。

    exception queue.Full

    当队列满时,非阻塞的put()或者put_nowait()被调用,将抛出该异常。

    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
    复制代码
     
     
     
  • 相关阅读:
    ubuntu下安装maven
    159.Longest Substring with At Most Two Distinct Characters
    156.Binary Tree Upside Down
    155.Min Stack
    154.Find Minimum in Rotated Sorted Array II
    153.Find Minimum in Rotated Sorted Array
    152.Maximum Product Subarray
    151.Reverse Words in a String
    150.Evaluate Reverse Polish Notation
    149.Max Points on a Line
  • 原文地址:https://www.cnblogs.com/MY0213/p/8997461.html
Copyright © 2011-2022 走看看