Python 队列:FIFO、LIFO 示例

⚡ 智能摘要

Python 队列是一种线性数据结构,用于存储元素并按预定顺序释放它们。队列模块提供了先进先出 (FIFO)、后进先出 (LIFO) 和优先级等变体,用于安全地管理任务、缓冲数据以及协调线程间的工作。

  • 🔢 FIFO: 队列类会先移除最旧的元素,非常适合任务调度和缓冲。
  • 🔁 后进先出: LifoQueue 类会首先移除最新添加的元素,其行为类似于堆栈。
  • 📦 核心方法: put()、get()、qsize()、empty() 和 full() 管理项目并报告队列状态。
  • 🧵 线程安全: 队列模块负责处理锁定,因此多个线程可以安全地共享一个队列。
  • 🎯 优先级: PriorityQueue 按优先级而不是按插入顺序释放项目。
  • 🤖 人工智能帮助: AI 助手根据简单的提示生成队列代码并解释 FIFO 和 LIFO 的权衡。

Python 排队顺序:先进先出(FIFO)、后进先出(LIFO)

什么是 Python 队列?

队列是存放数据的容器。最先输入的数据将最先被移除,因此队列也被称为“先进先出”(FIFO)。队列有前后两端。项目从后端输入,从前端移除。

如何 Python 排队工作吗?

队列可以很容易地与现实世界中的例子进行比较:在售票柜台排队等候的人,站得最前面的人将首先拿到票,然后是下一个人,依此类推。队列数据结构也遵循同样的逻辑。

以下是队列的示意图:

Python 排队工作

表示项目插入队列的点。在此示例中,7 是该点的值。

面前 表示队列中项目将被移除的点。如果从队列中移除一个项目,则将获得的第一个元素是 1,如图所示。

项目 1 是第一个插入队列的项目,而移除它时又是第一个出来的。因此,该队列称为先进先出 (FIFO)

Python 排队工作

在队列中,项目是按顺序移除的,不能在中间移除。您不能随机地从队列中移除项目 5,要做到这一点,您必须移除 5 之前的所有项目。队列中的项目将按照插入的顺序移除。

队列类型 Python

主要有两种类型的队列 Python:

  • 先进先出队列:为此,最先进入的元素将最先出来。要使用 FIFO,您必须调用 队列() 来自队列模块的类。
  • 后进先出队列:在这里,最后输入的元素将最先出来。要使用 LIFO,您必须调用 后进队列() 来自队列模块的类。

Python 队列安装

在 Python 中使用队列非常简单。以下是在代码中使用队列的步骤。

步骤1) 您只需导入队列模块,如下所示:

import queue

该模块默认随 python 提供,您无需进行任何额外安装即可开始使用队列。队列有两种类型:FIFO(先进先出)和 LIFO(后进先出)。

步骤2) 要使用 FIFO 队列,请使用导入的队列模块调用 Queue 类,如下所示:

import queue
q1 = queue.Queue()

步骤3) 要使用 LIFO 队列,请调用 LifoQueue() 类,如下所示:

import queue
q1 = queue.LifoQueue()

Queue 和 LifoQueue 类中可用的方法

以下是 Queue 和 LifoQueue 类中的重要方法:

  • 放置(物品): 这会将该项目放入队列中。
  • 得到(): 这将从队列中返回一个项目。
  • 空的(): 如果队列为空则返回 true,如果存在项目则返回 false。
  • qsize(): 返回队列的大小。
  • 满的(): 如果队列已满则返回 true,否则返回 false。

先进先出队列示例

在先进先出的情况下,先入的元素将最先出来。

在队列中添加项目

让我们来研究一个在队列中添加项目的示例。要开始使用队列,首先导入模块队列,如下例所示。

要添加项目,您可以使用 put() 方法,如示例所示:

import queue
q1 = queue.Queue()
q1.put(10) #this will additem 10 to the queue.

默认情况下,队列的大小是无限的,您可以向其中添加任意数量的项目。如果您想定义队列的大小,可以按如下方式进行操作

import queue
q1 = queue.Queue(5) #The max size is 5.
q1.put(1)
q1.put(2)
q1.put(3)
q1.put(4)
q1.put(5)
print(q1.full()) # will return true.

输出:

True

现在队列的大小为 5,并且不会接收超过 5 个项目,方法 q1.full() 将返回 true。添加任何项目都不会再执行代码。

从队列中删除一个项目

要从队列中删除项目,可以使用名为 get() 的方法。调用此方法时,可以从队列中删除项目。

以下示例显示如何从队列中删除一个项目。

import queue
q1 = queue.Queue()
q1.put(10)

item1 = q1.get()

print('The item removed from the queue is ', item1)

输出:

The item removed from the queue is  10

后进先出队列示例

在后进先出队列的情况下,最后进入的元素将最先出来。

要使用 LIFO(即后进先出队列),我们需要导入队列模块并使用 LifoQueue() 方法。

在队列中添加项目

在这里我们将了解如何将项目添加到 LIFO 队列。

import queue
q1 = queue.LifoQueue()
q1.put(10)

您必须在 LifoQueue 上使用 put() 方法,如上例所示。

从队列中删除一个项目

要从 LIFOqueue 中删除一个项目,您可以使用 get() 方法。

import queue
q1 = queue.LifoQueue()
q1.put(10)

item1 = q1.get()

print('The item removed from the LIFO queue is ', item1)

输出:

The item removed from the LIFO queue is  10

在队列中添加多个项目

在上面的例子中,我们了解了如何为 FIFO 和 LIFOqueue 添加和删除单个项目。现在我们将了解如何添加和删除多个项目。

在 FIFOqueue 中添加项目

import queue
q1 = queue.Queue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

从 FIFOqueue 中删除一个项目

import queue
q1 = queue.Queue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

while not q1.empty():
print("The value is ", q1.get()) # get() will remove the item from the queue.

输出:

The value is  0
The value is  1
The value is  2
The value is  3
The value is  4
The value is  5
The value is  6
The value is  7
The value is  8
The value is  9
The value is  10
The value is  11
The value is  12
The value is  13
The value is  14
The value is  15
The value is  16
The value is  17
The value is  18
The value is  19

在 LIFOqueue 中添加项目

import queue
q1 = queue.LifoQueue()
for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

从 LIFOqueue 中删除一个项目

import queue
q1 = queue.LifoQueue()

for i in range(20):
    q1.put(i) # this will additem from 0 to 20 to the queue

while not q1.empty():
print("The value is ", q1.get()) # get() will remove the item from the queue.

输出:

The value is  19
The value is  18
The value is  17
The value is  16
The value is  15
The value is  14
The value is  13
The value is  12
The value is  11
The value is  10
The value is  9
The value is  8
The value is  7
The value is  6
The value is  5
The value is  4
The value is  3
The value is  2
The value is  1
The value is  0 

排序队列

下面的例子显示了队列排序。排序使用的算法是冒泡排序。

import queue
q1 = queue.Queue()
#Addingitems to the queue
q1.put(11)
q1.put(5)
q1.put(4)
q1.put(21)
q1.put(3)
q1.put(10)

#using bubble sort on the queue
n =  q1.qsize()
for i in range(n):
    x = q1.get() # the element is removed
    for j in range(n-1):
        y = q1.get() # the element is removed
        if x > y :  
            q1.put(y)   #the smaller one is put at the start of the queue
        else:
            q1.put(x)  # the smaller one is put at the start of the queue
            x = y     # the greater one is replaced with x and compared again with nextelement
    q1.put(x)

while (q1.empty() == False): 
print(q1.queue[0], end = " ")  
        q1.get()

输出:

3 4 5 10 11 21

Rev读取队列

要反转队列,您可以使用另一个队列和递归。

下面的例子展示了如何反转队列。

计费示例:

import queue
q1 = queue.Queue()

q1.put(11)
q1.put(5)
q1.put(4)
q1.put(21)
q1.put(3)
q1.put(10)

def reverseQueue (q1src, q2dest) :  
    buffer = q1src.get()
    if (q1src.empty() == False) :
reverseQueue(q1src, q2dest)      #using recursion
    q2dest.put(buffer)
return q2dest

q2dest = queue.Queue()
qReversed = reverseQueue(q1,q2dest)

while (qReversed.empty() == False): 
print(qReversed.queue[0], end = " ")  
        qReversed.get()

输出:

10 3 21 4 5 11

常见问题

队列是先进先出(FIFO)的,所以最旧的元素先离开;而栈是后进先出(LIFO)的,其中最新的元素先离开。 Python的队列模块提供 Queue 用于 FIFO 行为,以及 LifoQueue 用于堆栈行为。

是的。队列、后进先出队列和优先级队列都是为多线程程序设计的,它们内部处理锁定,因此多个生产者和消费者线程可以共享一个队列,而不会出现竞争条件或数据损坏。

queue.Queue 是线程安全的,专为生产者-消费者线程设计。collections.deque 是一个速度更快的通用双端队列,适用于单线程代码,支持从两端快速追加和弹出元素。

PriorityQueue 按照优先级顺序而非插入顺序释放元素。你放入 (优先级, 数据) 元组,get() 方法首先返回优先级最低的元素,这很适合调度器和最短路径算法。

默认情况下,`get()` 函数会阻塞并等待直到有新元素可用。传递 `block=False` 或使用 `get_nowait()` 函数可以立即抛出 `queue.Empty` 异常,而无需等待新元素。

将 maxsize 参数传递给构造函数,例如 queue.Queue(5)。当队列已满时,put() 函数会阻塞,直到有空间释放,并且 full() 函数返回 True。maxsize 为 0 表示队列无限制。

AI 助手可以生成生产者-消费者队列代码,解释先进先出 (FIFO) 和后进先出 (LIFO) 的优缺点,并建议 queue.Queue、deque 或 asyncio.Queue 哪种更适合你的场景。它们还能帮助发现死锁和缺失的 task_done() 调用。

是的。GitHub Copilot 可以根据评论自动补全队列设置、put() 和 get() 循环以及工作线程。智能 AI 工具更进一步,会将阻塞代码重构为使用 asyncio.Queue,并在整个文件中添加错误处理。

总结一下这篇文章: