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
    复制代码
     
     
     
  • 相关阅读:
    redis是什么?
    mysql用户权限设置
    大白话说Java反射:入门、使用、原理 (转)
    iptables只允许指定ip访问本机的指定端口
    CSS系列——前端进阶之路:初涉Less
    MySQL分页查询优化
    linux 面试题
    CSS中定义CLASS时,中间有空格和没空格的区别是什么?
    MySQL Explain详解
    EBS 系统当前完成请求时间监测
  • 原文地址:https://www.cnblogs.com/MY0213/p/8997461.html
Copyright © 2011-2022 走看看