详解Python中 queue.queue 和 collections.deque 的区别

  • Post category:Python

Python中queue和deque都是用来进行队列操作的数据结构,它们具有相似和不同的特点。下面是它们之间的区别和使用场景:

queue.queue

queue.queue是Python标准库中的一个线程安全的FIFO队列。即,先进先出,后进后出。它在多线程条件下非常实用,因为它可以同步多个线程的操作,避免数据竞争,让线程之间更加安全和可靠。

假设我们需要爬取网页,并将网页的内容存储在队列中。代码如下:

import queue

url_queue = queue.Queue()

def crawl(url_queue):
    while True:
        url = url_queue.get()
        if url == None:
            break
        print('Get url:', url)

for i in range(10):
    url_queue.put('http://example.com/%d' % i)

crawl(url_queue)

代码说明:

  • 在第1行中,我们导入了标准库中的queue模块。
  • 在第3行中,我们创建了一个空的队列,并将其赋值给变量url_queue。
  • 在第5-11行中,我们定义了一个crawl函数,该函数在不断地从队列中获取一个URL,并在控制台中打印它。当队列为空时,该函数终止循环。
  • 在第13行中,我们通过循环将10个URL添加到队列中。
  • 在第15行中,我们调用了crawl函数,并将队列传递给它。

运行脚本后,输出结果如下:

Get url: http://example.com/0
Get url: http://example.com/1
Get url: http://example.com/2
Get url: http://example.com/3
Get url: http://example.com/4
Get url: http://example.com/5
Get url: http://example.com/6
Get url: http://example.com/7
Get url: http://example.com/8
Get url: http://example.com/9

collections.deque

collections.deque是双端队列(也称deque),支持从队列的两端进行操作。如果我们需要快速地在队列前端/后端添加或删除元素,那么deque是更好的选择。

例如,我们可以使用deque实现一个简单的消息队列,从队列的前端/后端推入/弹出消息。代码如下:

from collections import deque

message_queue = deque()

def push_message_front(queue, message):
    queue.appendleft(message)

def push_message_back(queue, message):
    queue.append(message)

def pop_message_front(queue):
    return queue.popleft()

def pop_message_back(queue):
    return queue.pop()

for i in range(10):
    push_message_front(message_queue, 'Message %d' % i)

while len(message_queue) > 0:
    print(pop_message_back(message_queue))

代码说明:

  • 在第1行中,我们从标准库中导入了deque。
  • 在第3行中,我们创建了一个空的双端队列,并将其赋值给变量message_queue。
  • 在第5-12行中,我们定义了4个函数,分别用于在双端队列的前端/后端排入/弹出消息。
  • 在第14-16行中,我们通过循环将10个消息从队列的前端排入队列。
  • 在第18-20行中,我们通过循环不断地从队列的后端弹出消息,并将其打印到控制台中。

运行脚本后,输出结果如下:

Message 9
Message 8
Message 7
Message 6
Message 5
Message 4
Message 3
Message 2
Message 1
Message 0

总结:

-queue.Queue 应该用于多线程/进程同步处理数据,避免数据竞争。

-collections.deque 应该用于需要在队列的任一端快速添加或删除元素的场景。它采用了双向链表来实现队列结构。

-在 Python 2.x 版本中,queue.Queue和有deque不是标准库,它们要独立安装(PyPi)。在 Python 3.x 版本中,它们已成为标准库。