Python 队列指南

Python 队列指南

介绍

从存储简单的整数到管理复杂的工作流程,数据结构为强大的应用程序奠定了基础。 其中, 队列 常常显得既有趣又无处不在。 想一想——一个 银行排队、在快餐柜台等待轮到您、或者在计算机系统中缓冲任务——所有这些场景都与队列机制产生共鸣。

排队的第一个人先得到服务,新来的人最后加入。 这是队列实际运行的一个示例!

队列指南-in-python-01.png

对于开发人员来说,尤其是 Python 开发人员,队列不仅仅是计算机科学教科书中的理论构造。 它们构成了许多应用程序的底层架构。 从管理打印机中的任务到确保直播中数据流的无缝传输,队列发挥着不可或缺的作用。

在本指南中,我们将深入研究队列的概念,探索它们的特性、实际应用,最重要的是,如何在 Python 中有效地实现和使用它们。

什么是队列数据结构?

在数据结构领域中,我们经常遇到具有不同数据输入和检索规则的容器。 其中, 队列 因其优雅和直率而脱颖而出。

先进先出原则

从本质上讲,队列是一种线性数据结构,遵循 先进先出(FIFO) 原则。 这意味着添加到队列中的第一个元素将是第一个被删除的元素。 可以将其比作一个相关场景:考虑售票柜台前排队的顾客。 先到的人先拿到票,随后到达的人在最后排队等候。

请注意: 队列有两端 – 后部和前部。 前面表示将从何处删除元素,后面表示将在何处添加新元素。

基本队列操作

  • 入队 – 的行为 添加 一个元素到末尾()的队列。

    队列指南-in-python-02.png

  • 出队 – 的行为 删除 的一个元素 队列的。

    队列指南-in-python-03.png

  • 窥视或正面 – 在许多情况下,仅观察前面的元件而不将其移除是有益的。 此操作使我们能够做到这一点。

  • 为IsEmpty – 帮助确定队列是否有任何元素的操作。 在操作取决于队列中是否有数据的情况下,这可能至关重要。

请注意: 虽然某些队列的大小有限(有界队列),但其他队列可能会在系统内存允许的情况下增长(无界队列)。

队列的简单性和清晰的操作规则使其非常适合软件开发中的各种应用,尤其是需要有序、系统处理的场景。

然而,理解理论只是第一步。 随着我们继续前进,我们将深入研究实际方面,说明如何在 Python 中实现队列。

如何在 Python 中实现队列 – 列表、双端队列、队列模块

Python 凭借其丰富的标准库和用户友好的语法,提供了多种实现和使用队列的机制。 虽然所有这些都服务于队列管理的基本目的,但它们也有其细微差别、优点和潜在缺陷。 让我们剖析每种方法,说明其机制和最佳用例。

请注意: 在执行操作之前,请务必检查队列的状态。 例如,在出队之前,验证队列是否为空以避免错误。 同样,对于有界队列,请确保在排队之前有空间。

使用Python列表实现队列

使用Python的内置列表来实现队列是直观和直接的。 不需要外部库或复杂的数据结构。 然而,这种方法对于大型数据集可能效率不高。 从列表开头删除一个元素 (pop(0))需要线性时间,这可能会导致性能问题。

请注意: 对于需要高性能或处理大量数据的应用程序,请切换到 collections.deque 入队和出队的时间复杂度恒定。

让我们首先创建一个列表来表示我们的队列:

queue = []

将元素添加到队列末尾(入队)的过程无非是将它们追加到列表中:


queue.append('A')
queue.append('B')
queue.append('C')
print(queue) 

此外,从队列前面删除元素(出队)相当于删除列表的第一个元素:


queue.pop(0)
print(queue) 

运用 集合.deque 实现队列

这种方法非常有效,因为 deque 是使用一个 双链表。 它支持从两端快速添加和弹出 O(1)。 这种方法的缺点是 对于初学者来说不太直观。

首先,我们将导入 deque 来自的对象 collections 模块并初始化我们的队列:

from collections import deque queue = deque()

现在,我们可以使用 append() 将元素入队的方法和 popleft() 从队列中取出元素的方法:

查看我们的 Git 学习实践指南,其中包含最佳实践、行业认可的标准以及随附的备忘单。 停止谷歌搜索 Git 命令,实际上 学习 它!


queue.append('A')
queue.append('B')
queue.append('C')
print(queue) queue.popleft()
print(queue) 

使用 Python 队列 实现队列的模块

queue Python 标准库中的模块提供了一种更专业的队列管理方法,可满足各种用例:

  • 简单队列 – 一个基本的 FIFO 队列
  • 后进队列 – LIFO 队列,本质上是一个堆栈
  • 优先队列 – 元素根据分配的优先级出队

请注意: 选择 queue 模块,其设计为 线程安全的。 这确保了队列上的并发操作不会导致不可预测的结果。

这种方法很棒,因为它是专门为队列操作而设计的。 但是,说实话,对于简单的场景来说,这可能有点过分了。

现在,让我们开始使用 queue 模块通过将其导入到我们的项目中:

import queue

由于我们正在实现一个简单的 FIFO 队列,因此我们将使用 SimpleQueue() 构造函数:

q = queue.SimpleQueue()

入队和出队操作是使用以下实现的 put()get() 来自的方法 queue 模块:


q.put('A')
q.put('B')
q.put('C')
print(q.queue) q.get()
print(q.queue) 

请注意: 队列操作可能会引发异常,如果不处理这些异常,可能会中断应用程序的流程。 为了防止这种情况,请将队列操作包装在 try-except 块。

例如,处理 queue.Empty 使用时出现异常 queue 模块:

import queue q = queue.SimpleQueue() try: item = q.get_nowait()
except queue.Empty: print("Queue is empty!")

选择哪种实现?

您选择的 Python 队列实现应该符合您的应用程序的要求。 如果您正在处理大量数据或需要优化性能, collections.deque 是一个令人信服的选择。 然而,对于多线程应用程序或当优先级发挥作用时, queue 模块提供了强大的解决方案。 对于快速脚本或刚开始使用时,Python 列表可能就足够了,但请始终警惕潜在的性能陷阱。

请注意: 当 Python 已经提供了强大的内置解决方案时,通过自定义实现队列操作来重新发明轮子。
在制作自定义解决方案之前,请熟悉 Python 的内置产品,例如 dequequeue 模块。 通常,它们可以满足广泛的要求,从而节省时间并减少潜在的错误。

深入探讨:Python 中的高级队列概念

对于那些掌握了队列基本机制并渴望深入研究的人来说,Python 提供了大量高级概念和技术来改进和优化基于队列的操作。 让我们揭示其中一些复杂的方面,为您提供一系列工具来处理更复杂的场景。

双端队列 双端队列

虽然我们之前已经探索过 deque 作为一个 FIFO 队列,它还支持 LIFO(后进先出)操作。 它允许您以 O(1) 的复杂度从两端追加或弹出元素:

from collections import deque dq = deque()
dq.appendleft('A') dq.append('B') dq.pop() dq.popleft() 

优先队列 在行动

当处理顺序取决于优先级时,使用简单的 FIFO 队列可能会导致效率低下或出现不良结果,因此,如果您的应用程序要求根据某些标准在其他元素之前处理某些元素,请使用 PriorityQueue。 这确保了元素根据其设置的优先级进行处理。

看一下我们如何为添加到队列中的元素设置优先级。 这要求我们传递一个元组作为参数 put() 方法。 元组应包含优先级作为其第一个元素,实际值作为第二个元素:

import queue pq = queue.PriorityQueue()
pq.put((2, "Task B"))
pq.put((1, "Task A")) pq.put((3, "Task C")) while not pq.empty(): _, task = pq.get() print(f"Processing: {task}")

这将为我们提供以下内容:

Processing: Task A
Processing: Task B
Processing: Task C

请注意我们如何以与队列中存储的顺序不同的顺序添加元素。 这是因为我们在 put() 向优先级队列添加元素时的方法。

实现循环队列

循环队列(或环形缓冲区)是一种高级数据结构,其中最后一个元素连接到第一个元素,确保循环流。 deque 可以使用其模仿这种行为 maxlen 属性:

from collections import deque circular_queue = deque(maxlen=3)
circular_queue.append(1)
circular_queue.append(2)
circular_queue.append(3) circular_queue.append(4)
print(circular_queue) 

结论

队列是基本而强大的,它在各种实际应用和计算问题中找到了本质。 从操作系统中的任务调度到管理打印后台处理程序或 Web 服务器请求中的数据流,队列的影响是深远的。

Python 提供了丰富的工具和库来处理队列。 从简单的基于列表的快速脚本队列到高效的 deque 对于性能关键型应用程序,该语言真正满足了一系列需求。

时间戳记:

更多来自 堆栈滥用