Learn Python – Queue in Python- Basic and advance

In this tutorial, we will discuss the Queue’s simple concepts and built-in Queue category and enforce it using the Python code.

What is the Queue?

A queue is a linear type of statistics structure used to shop the facts in a sequentially. The thought of queue is primarily based on the FIFO, which skill “First in First Out”. It is also regarded as “first come first severed”. The queue has the two ends front and rear. The subsequent factor is inserted from the rear cease and eliminated from the front end.

For example – There are 20 computers in the computer science lab and related to a single printer. The students prefer to print their paper; the printer will print the first venture and second, so on. If we are the last in line, we want to wait till all different duties are accomplished that in advance of ours.

The operating device manages the queue for processing the various techniques within a computer.

Operations in Python

We can function the following operations in the Queue.

Enqueue – The enqueue is an operation where we add items to the queue. If the queue is full, it is a condition of the Queue The time complexity of enqueue is O(1).

Dequeue – The dequeue is an operation where we remove an element from the queue. An element is removed in the same order as it is inserted. If the queue is empty, it is a condition of the Queue Underflow. The time complexity of dequeue is O(1).

Front – An element is inserted in the front end. The time complexity of front is O(1).

Rear – An element is removed from the rear end.. The time complexity of the rear is O(1).

Methods Available in Queue

Python provides the following methods, which are in many instances used to perform the operation in Queue.

put(item) – This function is used to insert element to the queue.

get() – This function is used to extract the element from the queue.

empty() – This function is used to check whether a queue is empty or not. It returns true if queue is empty.

qsize – This function returns the length of the queue.

full() – If the queue is full returns true; otherwise false.

We will research these features in the under sections.

The built-in Python List

The list can be used as the queue, but it is now not suitable for a overall performance perspective. Python gives built-in methods insert() and pop() function to add and get rid of elements. Lists are pretty slow due to the fact if we insert a new thing to the list, all elements require transferring through one. It takes O(n) time. So lists are advocated in-place of queue. Let’s understand the following example of how a listing can be used as a queue.

Example –

que = []  
  
que.append('Apple')  
que.append('Mango')  
que.append('Papaya')  
  
print(que)  
  
# List is slow!  
print(que.pop(0))  

Output:

['Apple', 'Mango', 'Papaya']
Apple

Explanation –

We have described the empty listing in the above code and inserted a few elements the usage of append() method. It will add an element to the cease of the list.

Adding Element to a Queue (Enqueue)

We can add the element from to the rear end. This procedure is additionally known as enqueue. We create a Queue class the place we will implement the First-in-First-Out concept. Let’s recognize the following example.

Example –

class Queue:  
  
  def __init__(self):  
      self.queue = list()  
  
  def add_element(self,val):  
# Insert method to add element  
      if val not in self.queue:  
          self.queue.insert(0,val)  
          return True  
      return False  
  
  def size(self):  
      return len(self.queue)  
  
TheQueue = Queue()  
TheQueue.add_element("Apple")  
TheQueue.add_element("Mango")  
TheQueue.add_element("Guava")  
TheQueue.add_element("Papaya")  
  
print("The length of Queue: ",TheQueue.size())  

Output:

The length of Queue:  4

Removing Element from a Queue (Dequeue)

We can cast off the factor shape the rear end. This manner is known as a dequeue. In the following example, we use the built-in pop() approach to dispose of an factor from the list.

Example –

class Queue:  
  
  def __init__(self):  
      self.queue = list()  
  
  def add_element(self,val):  
# Insert method to add element  
      if val not in self.queue:  
          self.queue.insert(0,val)  
          return True  
      return False  
# Pop method to remove element  
  def remove_element(self):  
      if len(self.queue)>0:  
          return self.queue.pop()  
      return ("Queue is Empty")  
  
que = Queue()  
que.add_element("January")  
que.add_element("February")  
que.add_element("March")  
que.add_element("April")  
  
print(que)  
print(que.remove_element())  
print(que.remove_element())  

Output:

January
February

Explanation –

In the above code, we have defined a type named Queue and constructor in it. We assigned an listing constructor to the queue variable. Then, we described two techniques – add_element() and remove_element(). In the add_element() block, we take a look at the situation if the fee is now not in Queue. If fee is not present, insert the element.

In the remove_element() characteristic block, we check the condition of whether a queue is not underflow. If it returns false, then dispose of the element one by one.

Sorting the Queue

In the following example, we have sorted the factors of the queue.

Example –

import queue  
q = queue.Queue()  
  
q.put(14)  
q.put(27)  
q.put(11)  
q.put(4)  
q.put(1)  
  
  
# Here, we use bubble sort algorithm for sorting  
n =  q.qsize()  
for i in range(n):  
    # Remove the element  
    x = q.get()  
    for j in range(n-1):  
        # Remove the element  
        y = q.get()  
        if x > y :  
            # put the smaller element at the beginning of the queue  
            q.put(y)  
        else:  
            # the smaller one is put at the start of the queue  
            q.put(x)  
            x = y    # The greater element is replaced by the x and check again  
    q.put(x)  
  
while (q.empty() == False):   
    print(q.queue[0], end = " ")    
    q.get()  

Output:

1 4 11 14 27

The Queue Module

Python presents the queue module to put into effect multi-producer, multi-consumer queues. The queue module presents Queue type which is specially used for the threaded programming. The Queue class implements all the required locking semantics.

We can operate all the operation the use of the in-built queue class.

Working With queue.Queue Class

The queue module contains a number of classes. The Queue is one of the necessary training of them. This is very useful in the parallel computing and multiprogramming. Let’s recognize the following example of the queue. Queue class0uii

Example –

from queue import Queue  
que = Queue()  
  
que.put('Apple')  
que.put('Mango')  
que.put('Papaya')  
  
print(que)  
  
  
print(que.get())  
  
print(que.get())  
  
print(que.get())  
  
print(que.get_nowait())  
  
print(que.get())  

Output:

<queue.Queue object at 0x00000114B30656A0>
Apple
Mango
Papaya
Traceback (most recent call last):
  File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/Queue.py", line 78, in <module>
    print(que.get_nowait())
  File "C:\Python\lib\queue.py", line 198, in get_nowait
    return self.get(block=False)
  File "C:\Python\lib\queue.py", line 167, in get
    raise Empty
_queue.Empty

Working With collection.deque Class

The collection.deque class is used to put into effect a double-ended queue that helps including and removing component from each ends. It takes O(1) time to complete the process.

The deque category can be used in each Queue and as stacks because it removes and provides factors effectively.

The collection.deque can be a excellent preference for queue records structure in Python’s general library.

Example –

from collections import deque  
que = deque()  
  
que.append('Apple')  
que.append('Mango')  
que.append('Banana')  
  
print(que)  
deque(['Apple ', 'Mango', 'Banana'])  
  
print(que.popleft())  
  
print(que.popleft())  
  
print(que.popleft())  
  
  
que.popleft()  

Output:

deque(['Apple', 'Mango', 'Banana'])
Apple
Mango
Banana
Traceback (most recent call last):
  File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/Queue.py", line 101, in <module>
    que.popleft()
IndexError: pop from an empty deque

The multiprocessing.Queue Class

The multiprocessing.Queue class is used to enforce queued objects for processed in parallel by way of multicurrent workers. The multiprocessing.Queue shares records between processes and can store any pickle-able object. Let’s apprehend the following example.

Example –

from multiprocessing import Queue  
que = Queue()  
  
que.put('Apple')  
que.put('Mango')  
que.put('Banana')  
  
print(que)  
  
print(que.get())  
  
print(que.get())  
  
print(que.get())  

Output:

<multiprocessing.queues.Queue object at 0x000002CA073356A0>
Apple
Mango
Banana

Priority Queue in Python

A priority queue is a distinctive type of queue in the data-structure. As the name suggest, it varieties the factors and dequeues the elements primarily based on their priorities.

Unlike everyday queue, it retrieves the highest-priority element as a substitute of the next element. The priority of character factors is decided by way of ordering utilized to their keys.

Priority queues are most recommended to handling scheduling troubles where some duties will manifest primarily based on priorities.

For instance – An working device project is the quality instance of a priority queue – It executes the high priority over lower-priority tasks (downloading updates in the background). The mission scheduler can enable the highest-priority tasks to run first.

There are a variety of ways to enforce a precedence queue in Python. Let’s apprehend the following ways.

Manually Sorted List

We can use the sorted Python list as the precedence queue to rapidly identify and delete the smaller and biggest element. But inserting the new element is slow as it takes O(n) operations.

Therefore sorted list can be fantastic when there are will be few insertions into the precedence queue.

Let’s understand the following example –

Example –

pri_que = []  
  
pri_que.append((2, 'Apple'))  
pri_que.append((1, 'Mango'))  
pri_que.append((3, 'Banana'))  
  
# NOTE: Remember to re-sort every time  
#       a new element is inserted.  
pri_que.sort(reverse=True)  
  
while pri_que:  
    next_item = pri_que.pop()  
    print(next_item)  

Output:

(1, 'Mango')
(2, 'Apple')
(3, 'Banana')

The queue.PriorityQueue Class

This priority queue implements makes use of heapq internally and shares the identical time and house complexities.

The distinction is the priority queue is coordinated and grants locking semantics to backing more than one concurrent activities and consumers.

Example –

from queue import PriorityQueue  
q = PriorityQueue()  
  
q.put((2, 'Apple'))  
q.put((1, 'Banana'))  
q.put((3, 'Mango'))  
  
while not q.empty():  
    next_item = q.get()  
    print(next_item)  

Output:

(1, 'Banana')
(2, 'Apple')
(3, 'Mango')

We can choose any precedence queue implementation in the Python application however keep in thinking that queue.PriorityQueue is top default choice.

Conclusion

We have discussed all the basic ideas of queue and its implementation. It is similar to the general list, however performance-wise it is always better. We have additionally defined the precedence queue and its a range of approaches of implementation.