Where a stack is Last In, First Out, a queue flips the rule around: First In, First Out (FIFO). Think of a line of people waiting at a checkout counter — whoever arrived first gets served first, and new arrivals join at the back. That's the entire behavior of a queue: items are added at one end (the "back" or "rear") and removed from the other end (the "front").

The Two Core Operations

A queue supports enqueue (add to the back) and dequeue (remove from the front). The implementation detail that trips people up: if you use a plain Python list and call pop(0) to remove from the front, that's actually O(n), because every remaining element has to shift left by one to fill the gap — the exact same problem as inserting in the middle of an array. The fix is to use a structure designed for fast removal from both ends.

from collections import deque

class Queue:
    def __init__(self):
        self.items = deque()  # deque gives O(1) operations at both ends

    def enqueue(self, value):   # add to the back -- O(1)
        self.items.append(value)

    def dequeue(self):           # remove from the front -- O(1)
        if self.is_empty():
            raise IndexError("dequeue from empty queue")
        return self.items.popleft()

    def is_empty(self):
        return len(self.items) == 0

queue = Queue()
queue.enqueue("first")
queue.enqueue("second")
queue.enqueue("third")
print(queue.dequeue())  # "first" -- served in arrival order
print(queue.dequeue())  # "second"

Output:

first
second

Python's collections.deque is implemented as a doubly linked structure internally, which is exactly why it avoids the O(n) shifting problem a plain list has — both ends are cheap to add to and remove from, unlike indexing into the middle of an array.

Real-World Uses of Queues

Task scheduling: a print queue, a background job processor, or a web server's request-handling queue all process work in the order it arrived. Breadth-first search (BFS) on trees and graphs relies entirely on a queue to visit nodes level by level — explore everything at the current distance before moving further out, which is only possible because the queue preserves arrival order. Buffering: streaming data (like video chunks or messages between services) is often queued so a slower consumer doesn't lose anything a faster producer sends.

Queues vs Stacks: Same Interface, Opposite Behavior

It's worth noticing that a stack and a queue can be built from almost identical underlying code — both just restrict where you're allowed to add and remove elements. The only real difference is which end removal happens from: the same end as insertion (stack, LIFO) or the opposite end (queue, FIFO). That small rule change is enough to make them suited to completely different classes of problems — stacks for "undo" and nested matching, queues for fair, ordered processing and level-by-level traversal.