Heap data structure is mainly used to represent a priority queue. In Python, it is available using the “heapq” module. The property of this data structure in Python is that each time the smallest heap element is popped(min-heap). Whenever elements are pushed or popped, heap structure is maintained. The heap[0] element also returns the smallest element each time. Let’s see various Operations on the heap in Python.
Creating a simple heap
The heapify(iterable):- This function is used to convert the iterable into a heap data structure. i.e. in heap order.
Python3
# importing "heapq" to implement heap queue import heapq # initializing list li = [ 5 , 7 , 9 , 1 , 3 ] # using heapify to convert list into heap heapq.heapify(li) # printing created heap print ( "The created heap is : " ,( list (li))) |
The created heap is : [1, 3, 9, 7, 5]
Appending and Popping Items Efficiently
- heappush(heap, ele): This function is used to insert the element mentioned in its arguments into a heap. The order is adjusted, so that heap structure is maintained.
- heappop(heap): This function is used to remove and return the smallest element from the heap. The order is adjusted, so that heap structure is maintained.
Python3
# importing "heapq" to implement heap queue import heapq # initializing list li = [ 5 , 7 , 9 , 1 , 3 ] # using heapify to convert list into heap heapq.heapify(li) # printing created heap print ( "The created heap is : " , end = "") print ( list (li)) # using heappush() to push elements into heap # pushes 4 heapq.heappush(li, 4 ) # printing modified heap print ( "The modified heap after push is : " , end = "") print ( list (li)) # using heappop() to pop smallest element print ( "The popped and smallest element is : " , end = "") print (heapq.heappop(li)) |
The created heap is : [1, 3, 9, 7, 5] The modified heap after push is : [1, 3, 4, 7, 5, 9] The popped and smallest element is : 1
Appending and Popping simultaneously
- heappushpop(heap, ele):- This function combines the functioning of both push and pop operations in one statement, increasing efficiency. Heap order is maintained after this operation.
- heapreplace(heap, ele):- This function also inserts and pops elements in one statement, but it is different from the above function. In this, the element is first popped, then the element is pushed. i.e, the value larger than the pushed value can be returned. heapreplace() returns the smallest value originally in the heap regardless of the pushed element as opposed to heappushpop().
Python3
# importing "heapq" to implement heap queue import heapq # initializing list 1 li1 = [ 5 , 1 , 9 , 4 , 3 ] # initializing list 2 li2 = [ 5 , 7 , 9 , 4 , 3 ] # using heapify() to convert list into heap heapq.heapify(li1) heapq.heapify(li2) # using heappushpop() to push and pop items simultaneously # pops 2 print ( "The popped item using heappushpop() is : " , end = "") print (heapq.heappushpop(li1, 2 )) # using heapreplace() to push and pop items simultaneously # pops 3 print ( "The popped item using heapreplace() is : " , end = "") print (heapq.heapreplace(li2, 2 )) |
The popped item using heappushpop() is : 1 The popped item using heapreplace() is : 3
Find the largest and smallest elements from Heap in Python
- nlargest(k, iterable, key = fun): This function is used to return the k largest elements from the iterable specified and satisfy the key if mentioned.
- nsmallest(k, iterable, key = fun): This function is used to return the k smallest elements from the iterable specified and satisfy the key if mentioned.
Python3
# Python code to demonstrate working of # nlargest() and nsmallest() # importing "heapq" to implement heap queue import heapq # initializing list li1 = [ 6 , 7 , 9 , 4 , 3 , 5 , 8 , 10 , 1 ] # using heapify() to convert list into heap heapq.heapify(li1) # using nlargest to print 3 largest numbers # prints 10, 9 and 8 print ( "The 3 largest numbers in list are : " , end = "") print (heapq.nlargest( 3 , li1)) # using nsmallest to print 3 smallest numbers # prints 1, 3 and 4 print ( "The 3 smallest numbers in list are : " , end = "") print (heapq.nsmallest( 3 , li1)) |
The 3 largest numbers in list are : [10, 9, 8] The 3 smallest numbers in list are : [1, 3, 4]
Example:
Python3
import heapq # Initialize a list with some values values = [ 5 , 1 , 3 , 7 , 4 , 2 ] # Convert the list into a heap heapq.heapify(values) # Print the heap print ( "Heap:" , values) # Add a new value to the heap heapq.heappush(values, 6 ) # Print the updated heap print ( "Heap after push:" , values) # Remove and return the smallest element from the heap smallest = heapq.heappop(values) # Print the smallest element and the updated heap print ( "Smallest element:" , smallest) print ( "Heap after pop:" , values) # Get the n smallest elements from the heap n_smallest = heapq.nsmallest( 3 , values) # Print the n smallest elements print ( "Smallest 3 elements:" , n_smallest) # Get the n largest elements from the heap n_largest = heapq.nlargest( 2 , values) # Print the n largest elements print ( "Largest 2 elements:" , n_largest) |
Heap: [1, 4, 2, 7, 5, 3] Heap after push: [1, 4, 2, 7, 5, 3, 6] Smallest element: 1 Heap after pop: [2, 4, 3, 7, 5, 6] Smallest 3 elements: [2, 3, 4] Largest 2 elements: [7, 6]
This program creates a heap queue using the heapq module in Python and performs various operations such as converting a list into a heap, adding a new value to the heap, removing the smallest element from the heap, getting the n smallest and n largest elements from the heap.
Note that the heapq module in Python provides functions for performing heap operations on lists in-place, without creating a separate data structure for the heap. The heapq module is efficient and easy to use, making it a popular choice for implementing priority queues and other data structures in Python.
Advantages of using a heap queue (or heapq) in Python:
- Efficient: A heap queue is a highly efficient data structure for managing priority queues and heaps in Python. It provides logarithmic time complexity for many operations, making it a popular choice for many applications.
- Space-efficient: Heap queues are space-efficient, as they store elements in an array-based representation, minimizing the overhead associated with node-based data structures like linked lists.
- Easy to use: Heap queues in Python are easy to use, with a simple and intuitive API that makes it easy to perform basic operations like inserting, deleting, and retrieving elements from the heap.
- Flexible: Heap queues in Python can be used to implement various data structures like priority queues, heaps, and binary trees, making them a versatile tool for many applications.
Disadvantages of using a heap queue (or heapq) in Python:
- Limited functionality: Heap queues are primarily designed for managing priority queues and heaps, and may not be suitable for more complex data structures and algorithms.
- No random access: Heap queues do not support random access to elements, making it difficult to access elements in the middle of the heap or modify elements that are not at the top of the heap.
- No sorting: Heap queues do not support sorting, so if you need to sort elements in a specific order, you will need to use a different data structure or algorithm.
- Not thread-safe: Heap queues are not thread-safe, meaning that they may not be suitable for use in multi-threaded applications where data synchronization is critical.
Overall, heap queues are a highly efficient and flexible data structure for managing priority queues and heaps in Python, but may have limited functionality and may not be suitable for all applications.