Python中Queue和Collections的区别


队列是一种遵循FIFO(先进先出)交付方式的数据结构,即一组消息的顺序严格保持不变。它精确地处理所有消息一次,因此不会出现消息重复。

FIFO系统相对于标准交付方式的优势在于,由于应用了队列的批量处理,队列能够支持无限吞吐量。FIFO具有高吞吐量(通过流程的项目数量),并且可以处理比平均水平多得多的消息。

在Python中,队列可以通过两个主要的库来实现:collections库和queue库。尽管它们都用于队列实现,但两者之间存在许多差异,这些差异对于不同的用例场景可能是最佳的。主要区别列在下面

主要区别

类别 queue.Queue() collections.deque()
同步 'queue.Queue' 提供了安全的处理多线程操作的方法,因为它实现了同步。 'collections.deque' 默认情况下不同步,因此可能不适用于可能使用多个线程的操作。
功能 'queue.Queue' 特别用于队列实现以及FIFO交付系统,其中元素添加到末尾。它提供诸如put()和get()之类的函数,用于对队列中存在的元素进行入队和出队操作。 对于'collections.deque',它更像是一个标准的实现,同时实现了LIFO和FIFO的概念,因此也可以用于堆栈操作。诸如append()、pop()和popleft()之类的函数使您可以从两端添加和删除元素。
其他 'queue.Queue'除了基本的队列函数外,没有提供其他功能。 'collections.deque' 提供更多功能来修改或更改给定的队列,例如rotate()函数可以以任何方式旋转队列,remove()函数可以从deque中删除特定元素。
性能 从复杂度来看,'collections.deque'由于使用双向链表,速度更快。因此,它的复杂度为O(1),因此可以更快地执行操作。 在'queue.Queue'中,由于其同步开销,尤其是在多线程处理过程中,速度略慢。

queue.Queue

在Python中,queue模块提供了一个'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

我们首先导入queue模块并为queue类分配一个对象。然后我们使用put()函数入队元素。然后,我们初始化一个while循环,直到队列为空为止,不断地出队元素。然后将出队的元素打印为输出。

collections.deque

在Python中,collections.deque类用于引入双端队列数据结构。“Deque”代表“双端队列”。在此,可以有效地从队列的两端添加或删除元素。

语法

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

这里我们使用deque(双端队列)来展示对deque两端进行入队和出队操作。

20正常追加,然后60在20的左边追加到deque中。之后,可以使用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'。

更新于:2023年8月10日

130 次浏览

启动您的职业生涯

完成课程获得认证

开始学习
广告