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'。