Python 队列queue和集合collections的区别

Python 队列queue和集合collections的区别

队列是一种遵循FIFO(先进先出)传递方法的数据结构,即一组消息的顺序严格保留。它仅处理所有消息一次,因此没有消息的重复。

先进先出系统相对于标准传递方法的优势在于队列支持无限吞吐量,因为它应用了队列的批处理。FIFO具有高吞吐量(通过过程传递的项的数量)并且可以处理比平均值更多的消息。

在Python中,可以通过两个主要的库,collections和queue库,来实现队列。虽然它们都用于队列实现,但两者之间有许多不同之处,可以在不同的用例场景中进行优化。主要的区别如下:

主要区别

类别 queue.Queue() collections.deque()
同步操作 ‘queue.Queue’通过实现同步操作,提供了安全的多线程操作处理。 ‘collections.deque’默认情况下不是同步的,因此对于可能使用多个线程的操作可能不适用。
功能 ‘queue.Queue’专用于队列的实现,采用先进先出的投递系统,元素从末尾添加。它提供了put()和get()等函数,用于向队列中的元素进行入队和出队操作。 对于’collections.deque’而言,它更多地是一种标准实现,同时实现了后进先出和先进先出的概念,因此也可以用于栈操作。通过append()、pop()和popleft()等函数,您可以在双端队列中添加和删除元素。
杂项 ‘queue.Queue’除了基本的队列功能外,并没有提供太多其他功能。 ‘collections.deque’提供了更多的功能,可以使用像rotate()将队列以任意方式旋转,以及使用remove()来删除特定元素的函数来修改或更改给定队列。
性能 就复杂度而言,’collections.deque’由于使用了双向链表,因此更快。由于这个原因,它的复杂度为O(1),可以执行更快的操作。 在’queue.Queue’中,由于同步的开销,特别是在多线程进程中,速度稍慢一些。

queue.Queue

在Python中,queue模块提供了一个’Queue()’类,它提供了一种数据结构。Queue()类具有通过实现队列数据结构的队列方法。

语法

Queue().put(value)
Queue().get(value)

在这里,value是使用put()函数入队列的元素。要从队列中删除元素,我们使用get()函数进行出队列操作。

步骤

  • 导入库。

  • 初始化队列。

  • 将一些元素入队列。

  • 检查它们是否为空。

  • 如果不为空,则出队列元素并打印它们。

示例

#import the necessary library
from queue import Queue

#assign an object to the queue class
m_q=Queue()

#Enqueue elements in a queue
m_q.put(20)
m_q.put(40)
m_q.put(60)

#Dequeuing the elements and printing them
while not m_q.empty():
  i=m_q.get()
  print(i)

输出

20
40
60

我们首先导入队列模块并为队列类分配一个对象。然后,我们使用put()函数将元素入队。然后,我们初始化一个while循环,以便在队列为空之前一直出队元素。然后,出队的元素将作为输出打印出来。

collections.deque

在Python中,使用collections.deque类引入双向队列数据结构。”Deque”代表”double-ended queue”。在这种数据结构中,可以高效地从队列的两端添加或移除元素。

语法

deque().append(20)
deque().appendleft(60)
deque().pop()
deque().popleft()

在这里我们使用deque(双向队列)展示了在deque的两侧进行入队和出队操作。

20被正常地添加,然后60被添加到20的左侧。之后,可以使用pop()和popleft()函数对任一侧进行出队操作。

步骤

  • 导入库。

  • 初始化deque。

  • 从左侧或右侧添加元素。

  • 弹出元素。

  • 打印队列。

示例

from collections import deque

# Create a new deque
my_deque = deque()

# Add elements to the deque
my_deque.append(20)  # Add to the right end
my_deque.appendleft(40)  # Add to the left end
my_deque.append(60) #Add to right end
print("Initial deque: \n",my_deque)

# Remove elements from the deque
right_element = my_deque.pop()  # Remove from the right end
print("\nAfter removing element from right: \n",my_deque)

left_element = my_deque.popleft()  # Remove from the left end
print("\nAfter removing element from left :\n", my_deque)

# Print the deque's contents
my_deque.pop()
print("\nFinal deque: \n",my_deque)

输出

Initial deque: 
 deque([40, 20, 60])

After removing element from right: 
 deque([40, 20])

After removing element from left :
 deque([20])

Final deque: 
 deque([])

它的一些优点是

简化复杂度 collections.deque()’由于使用了双向链表,具有较低的复杂度,并且具有O(1)的复杂度,适用于队列的两端进行插入和删除操作的场景。
动态大小 与常规队列不同,其中容量是事先定义好的,存储非常严格,collections.deque可以动态改变队列的大小。在达到最大容量时,无需调整大小或复制元素。

结论

‘queue.Queue’ 和 ‘collections.deque’ 都用于队列的实现。但是,从性能上来看,在执行不同的操作时它们提供了非常微小的差异。但是,由于具有额外的功能,’collections.deque’ 被广泛使用。除了在多线程示例中关键的同步情况下,大多数情况下都使用 ‘collections.deque’。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程