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 版本中,它们已成为标准库。