Back to Python
2026-05-028 min read

Queues (Python Programming)

Learn Queues (Python Programming) step by step with clear examples and exercises.

Title: Mastering Queues in Python Programming

Why This Matters

Queues are fundamental data structures that play a crucial role in various real-world applications like operating systems, web servers, and simulation programs. They help manage tasks efficiently by ensuring that the first task added to the queue is the first one processed. In this lesson, we will delve deeper into understanding and implementing queues using Python.

Queues are an essential building block for many concurrent programming problems and algorithms, such as producer-consumer problems, breadth-first search (BFS), and job scheduling. Understanding how to use and implement queues effectively can significantly improve the efficiency of your programs.

Prerequisites

Before diving into queues, it's essential to have a solid grasp of the following concepts:

  1. Basic Python syntax (variables, data types, operators)
  2. Control structures (if-else statements, loops)
  3. List data structure and its methods
  4. Functions and modules in Python
  5. Understanding of exceptions and error handling in Python
  6. Familiarity with advanced list operations like slicing and concatenation
  7. Comprehension of Python's built-in deque data structure from the collections module
  8. Knowledge of concurrent programming concepts (optional but beneficial)

Core Concept

A queue is a collection of items where addition (enqueue) and removal (dequeue) occur at opposite ends. The end where items are added is called the rear, while the end from which items are removed is known as the front. In Python, we can implement queues using lists or deque (double-ended queue) from the collections module.

List Implementation of Queue

Here's an example implementation of a basic queue using a list:

def enqueue(items, item):
items.append(item)

def dequeue(items):
if not items:
raise Exception("Queue is empty.")
return items.pop(0)

def peek(items):
if not items:
raise Exception("Queue is empty.")
return items[0]

In the above code, we have defined three functions – enqueue, dequeue, and peek. The enqueue function appends an item to the end of the list, while the dequeue function removes an item from the front (head) of the list. The peek function returns the first item in the queue without removing it.

Deque Implementation of Queue

For more efficient enqueue and dequeue operations, we can use Python's built-in deque data structure from the collections module:

from collections import deque

def create_queue():
return deque()

def enqueue(queue, item):
queue.append(item)

def dequeue(queue):
if not queue:
raise Exception("Queue is empty.")
return queue.popleft()

def peek(queue):
if not queue:
raise Exception("Queue is empty.")
return queue[0]

In the above code, we have defined a new function create_queue to create an empty deque and implemented enqueue, dequeue, and peek functions for it. The deque data structure provides constant time complexity (O(1)) for both enqueue and dequeue operations.

Worked Example

Let's create a simple example where we enqueue and dequeue items from a queue using both list and deque implementations:

List implementation

items = []

enqueue(items, 10)

enqueue(items, 20)

enqueue(items, 30)

print("Queue after enqueuing:", items)

dequeued_item = dequeue(items)

print("Dequeued item (list):", dequeued_item)

print("Queue after dequeuing (list):", items)

peeked_item = peek(items)

print("Peeked item (list):", peeked_item)

Deque implementation

queue = create_queue()

enqueue(queue, 40)

enqueue(queue, 50)

enqueue(queue, 60)

print("\nQueue after enqueuing (deque):", queue)

dequeued_item = dequeue(queue)

print("Dequeued item (deque):", dequeued_item)

print("Queue after dequeuing (deque):", queue)

peeked_item = peek(queue)

print("Peeked item (deque):", peeked_item)


Output:

Queue after enqueuing: [10, 20, 30]

Dequeued item (list): 10

Queue after dequeuing (list): [20, 30]

Peeked item (list): 20

Queue after enqueuing (deque): deque([40, 50, 60])

Dequeued item (deque): 40

Queue after dequeuing (deque): deque([50, 60])

Peeked item (deque): 50

Common Mistakes

  1. Not checking if the queue is empty before dequeueing: It's crucial to check whether the queue is empty before attempting to dequeue an item. If the queue is empty, the dequeue function should raise an exception instead of returning a message or None.
  2. Incorrect implementation of enqueue and dequeue functions: Incorrect implementations can lead to issues like adding items at the wrong end or removing items from the wrong end. Make sure your enqueue and dequeue functions follow the FIFO (First-In, First-Out) principle.
  3. Misunderstanding the peek function: The peek function only returns the first item in the queue without removing it. It's essential to understand that this operation does not affect the size or order of the items in the queue.
  4. Not using a dedicated data structure for queues: While it is possible to implement queues using lists, it's more efficient and convenient to use built-in Python data structures like deque from the collections module.
  5. Ignoring exceptions: Properly handling exceptions when working with queues can help prevent unexpected errors and make your code more robust.
  6. Not considering the maximum size of a queue: In some cases, it's important to limit the maximum size of a queue to avoid running out of memory. This can be achieved by raising an exception when attempting to enqueue an item when the queue is full.
  7. Misusing the deque data structure: The deque data structure provides additional methods like appendleft, popleft, and rotate that can be useful in certain scenarios but may not always follow the FIFO principle. Be mindful of these differences when choosing between a list and deque implementation.

Common Mistakes (continued)

  1. Not implementing custom exception classes: Using custom exception classes for queue-related errors makes your code more organized, readable, and maintainable.
  2. Using the wrong data structure for specific use cases: When dealing with complex concurrent programming problems or when performance is a concern, using specialized data structures like PriorityQueue from the queue module may be beneficial.
  3. Not considering thread-safety: In multi-threaded applications, it's essential to ensure that your queue implementation is thread-safe to avoid race conditions and other synchronization issues.

Practice Questions

  1. Write a function that implements a priority queue using the heapq module from Python's standard library.
  2. Implement a producer-consumer problem using threads and a shared queue in Python.
  3. Create a custom exception class for an empty queue and use it in your implementation of the enqueue, dequeue, and peek functions.
  4. Write a function that checks if two given queues are identical in terms of their items and order.
  5. Implement a solution to the producer-consumer problem where the maximum size of the queue is limited using semaphores or locks.
  6. Create a custom exception class for an attempt to enqueue when the queue is full and use it in your implementation of the enqueue function.
  7. Write a function that sorts items in a queue based on their priority during dequeue operations using a list of tuples (item, priority).
  8. Implement a solution to the producer-consumer problem where producers produce items with different priorities and consumers consume them accordingly.
  9. Create a custom exception class for an attempt to dequeue from an empty queue and use it in your implementation of the dequeue function.
  10. Write a function that merges two queues into one while maintaining their order and preserving duplicates.

FAQ

  1. What is the time complexity of enqueue and dequeue operations for Python's built-in queue data structure?

Enqueue and dequeue operations in Python's built-in deque data structure have a constant time complexity of O(1).

  1. Can we implement custom exceptions for queue-related errors, like an empty queue or an attempt to enqueue when the queue is full?

Yes, you can create custom exceptions for such cases by defining a new exception class and raising it when appropriate.

  1. Is it possible to sort items in a queue based on their priority during dequeue operations?

Yes, you can implement a priority queue using a list of tuples (item, priority) and sort the list before processing the items. This solution may have a time complexity of O(n log n) for sorting.

  1. Can we limit the maximum size of a Python queue?

While Python's built-in deque data structure does not have a direct method to limit its maximum size, you can implement this functionality by raising an exception when attempting to enqueue an item when the queue is full.

  1. What are some common use cases for queues in real-world applications?

Queues are used extensively in various fields such as operating systems (process scheduling), web servers (request handling), and simulation programs (event handling). They help manage tasks efficiently by ensuring that the first task added to the queue is the first one processed.

  1. What are some specialized data structures for implementing queues in Python?

In addition to the built-in deque data structure, there are other specialized data structures like PriorityQueue from the queue module that can be useful for specific use cases. For example, PriorityQueue uses a binary heap and provides methods like heapify, heappush, and heappop.

  1. What is the difference between a list and deque when implementing a queue?

While both lists and deques can be used to implement queues, deques provide constant time complexity (O(1)) for enqueue and dequeue operations, making them more efficient in terms of performance. Lists, on the other hand, have O(n) complexity for these operations when dealing with appends and pops from the end.

  1. What are some best practices for implementing concurrent queues in Python?

When implementing concurrent queues in Python, it's essential to consider thread-safety by using locks or semaphores to synchronize access to the queue. Additionally, you should ensure that your implementation is scalable and can handle multiple producers and consumers efficiently.

Queues (Python Programming) | Python | XQA Learn