Related Articles

Related Articles

How to maintain dictionary in a heap in Python ?
  • Last Updated : 01 Oct, 2020

Prerequisites:

The dictionary can be maintained in heap either based on the key or on the value. The conventions to be maintained are listed below:

  • The key-value pair at index ‘i‘ is considered to be the parent of key-value pair at the indices 2k+1 and 2k+2.
  • For a min-heap, the parent key/value must be smaller than its children.
  • For a max-heap, the parent key/value must be larger than its children.

Examples:

Normal dictionary : {11:2, 0:4, 5:9, 22:7}

Heap based on keys of the dictionary : {0: 4, 1: 1, 5: 9, 22: 7, 11: 2}



Heap based on values of the dictionary : {11: 2, 0: 4, 5: 9, 22: 7}

This article shows how to maintain a dictionary in a min-heap using the heapq module.

Normal dictionary as a heap

The normal dictionary with integers/strings as the key can be maintained in a heap structure with the help of the heapq module. But this module expects a list to be passed. So the approach used here is :

  1. Convert the key-value pairs into a list of tuples.
  2. Pass the list of tuples to heapify() function.
  3. Convert the resulting list into a dictionary again.

Note: The heapify() on tuples considers the first element in the tuple for the process. Thus, by default, the dictionaries are maintained in heap, based on the key only.

Example 1: Based on the Key for integers

Consider a dictionary where the keys are positive integers and the values are their squares. Now, this should be maintained in a heap.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# import modules
import heapq as hq
  
# dictionary to be heapified
dict_1 = {11: 121, 2: 4, 5: 25, 3: 9}
  
# convert dictionary to list of tuples
di = list(dict_1.items())
  
print("dictionary into list :", di)
  
# converting into heap
hq.heapify(di)
  
print("Heapified list of tuples :", di)
  
# converting heap to dictionary
di = dict(di)
  
print("Dictionary as heap :", di)

chevron_right


Output

dictionary into list : [(11, 121), (2, 4), (5, 25), (3, 9)]
Heapified list of tuples : [(2, 4), (3, 9), (5, 25), (11, 121)]
Dictionary as heap : {2: 4, 3: 9, 5: 25, 11: 121}

Example 2: Based on key for String 



Consider a dictionary which has a combination of alphabets as key and their numbering as values. For example: “abc” : 123. This has to be maintained in heap. 

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# import modules
import heapq as hq
  
# dictionary to be heapified
dict_1 = {"yz": 2526, "ab": 12, "cd": 34, "ij": 910, "fg": 67}
  
# convert dictionary to list of tuples
di = list(dict_1.items())
  
print("dictionary into list :", di)
  
# converting into heap
hq.heapify(di)
  
print("Heapified list of tuples :", di)
  
# converting heap to dictionary
di = dict(di)
  
print("Dictionary as heap :", di)

chevron_right


Output:

dictionary into list : [(‘yz’, 2526), (‘ab’, 12), (‘cd’, 34), (‘ij’, 910), (‘fg’, 67)]
Heapified list of tuples : [(‘ab’, 12), (‘fg’, 67), (‘cd’, 34), (‘ij’, 910), (‘yz’, 2526)]
Dictionary as heap : {‘ab’: 12, ‘fg’: 67, ‘cd’: 34, ‘ij’: 910, ‘yz’: 2526}

Example 3: Based on the value

The approach slightly differs here. The steps to be carried out are:

  1. Extract the values in the dictionary and append to a list.
  2. Pass the list to heapify().
  3. Based on the heapified list values, reconstruct a new dictionary from the original one by iterating through it.

Here only the values satisfy the heap property and not necessarily the keys.

Example:

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# import the module
import heapq as hq
  
# dictionary to be heapified
li_dict={11:121,2:4,5:25,3:9}
  
# List to hold values from dictionary
heap_dict=[]
  
# extract the values from dictionary
for i in li_dict.values():
    heap_dict.append(i)
      
# heapify the values
hq.heapify(heap_dict)   
print("Values of the dict after heapification :",heap_dict)
  
# list to hold final heapified dictionary
new_dict=[]
  
# mapping and reconstructing final dictionary
for i in range(0,len(heap_dict)):
      
    # Iterating the oringinal dictionary
    for k,v in li_dict.items():
        
        if v==heap_dict[i] and (k,v) not in new_dict:
            new_dict.append((k,v))
              
new_dict=dict(new_dict)
  
print("Final dictionary :",new_dict)

chevron_right


Output

Values of the dict after heapification : [4, 9, 25, 121]
Final dictionary : {2: 4, 3: 9, 5: 25, 11: 121}

List of dictionaries as a heap

The examples seen above are based on a single dictionary. Consider a list of dictionaries which has to be maintained as a heap. The approach used is:

  • Convert each dictionary into a tuple using list comprehension.
  • Pass the list to heapify().
  • Convert the resulting list of heapified tuples into the dictionary.

Note: The heapify() on tuples considers the first element in the tuple for the process. Thus, by default, the dictionaries are maintained in heap, based on the key only.



Example :

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# import modules
import heapq as hq
  
# list of dictionaries
li_dict=[{11:121},{2:4},{5:25},{3:9}]
  
#temporary list to hold tuple of key-value pairs
heap_dict=[]
  
# conert each dict to tuple
heap_dict=[(k,v) for i in li_dict for k,v in i.items() ]
  
print("After extraction :",heap_dict)
  
# heapify the list of tuples
hq.heapify(heap_dict)   
  
print("Heapified key-value pairs :",heap_dict)
  
# reconvert to dictionary
final=dict(heap_dict)
print("Heapified dictionaries :",final)

chevron_right


Output

After extraction : [(11, 121), (2, 4), (5, 25), (3, 9)]
Heapified key-value pairs : [(2, 4), (3, 9), (5, 25), (11, 121)]
Heapified dictionaries : {2: 4, 3: 9, 5: 25, 11: 121}

Nested dictionaries

In the case of nested dictionaries, the task takes more steps to maintain the dictionary in heap. If the dictionary has to be maintained based on the key in a inner dictionary, then the following approach can be used.

  • Convert the dictionary into list of tuples where the key of the outer dictionary is tuple[0] and the inner dictionary is tuple[1].
  • Extract the values of the key in inner dictionaries into a list.
  • Apply heapify() on that list.
  • Re-construct a new dictionary by ordering them based on the heapified results.

For example, consider a record of employees as a nested dictionary. The record appears as given below:

{

   “emp01”:{

       “name”:”Kate”,

       “age”:22,

       “designation”: “Analyst”,

       “Salary”:30000

   },

   “emp02”:{

       “name”:”Rina”,

       “age”:20,

       “designation”:”Programmer”,

       “Salary”:25000

   },

   “emp03”:{

       “name”:”Vikas”,

       “age”:42,

       “designation”:”Manager”,

       “Salary”:35000

   },

   “emp04”:{

       “name”:”manish”,

       “age”:42,

       “designation”:”Manager”,

       “Salary”:15000

   }

}

 Now let us maintain this in a min-heap based on the salary values. Thus, the employee with minimum salary appears as the first record. For better readability and understanding we can split the code into functions.

Step 1:  Define the function to convert the dictionary into a list

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

def get_list(d):
      
    list_li=list(d.items())
      
    print("Dictionary as list",list_li,"\n")
      
    return(list_li)

chevron_right


Step 2: Define the function that performs heapification. Takes the list of tuples as parameter.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

def convert_heap(list_li):
      
    # list to hold salary values
    sal_li=[]
  
    # extrat salary values
    for i in range(0,len(list_li)):
        
        sal_li.append(list_li[i][1]['Salary'])
  
    print("Before heapify :",sal_li,"\n")
  
    # heapify the salary values
    hq.heapify(sal_li)
  
    print("After salary :",sal_li,"\n")
  
    # list to hold the final dictionary as heap
    final=[]
  
    # reconstruction of dictionary as heap
    # yields a list of tuples of key-value pairs
    for i in range(0,len(sal_li)):
        
        for j in range(0,len(sal_li)):
            
            if list_li[j][1]['Salary']==sal_li[i]:
                final.append(list_li[j])
              
    # list of tuples to dictionary
    final=dict(final)
     
    return final

chevron_right


Step 3: Define the dictionary and call the functions appropriately.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

nested_dict={
    "emp01":{
        "name":"Kate",
        "age":22,
        "designation": "Analyst",
        "Salary":30000
    },
    "emp02":{
        "name":"Rina",
        "age":20,
        "designation":"Programmer",
        "Salary":25000
    },
    "emp03":{
        "name":"Vikas",
        "age":42,
        "designation":"Manager",
        "Salary":35000
    },
    "emp04":{
        "name":"manish",
        "age":42,
        "designation":"Manager",
        "Salary":15000
    }
}
  
list_li=get_list(nested_dict)
  
final=convert_heap(list_li)
  
print("Dictionary as heap :",final)

chevron_right


Now putting all the code together we get a nested dictionary maintained in heap, based on the values of the salary.

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

import heapq as hq
  
def get_list(d):
      
    list_li=list(d.items())
      
    print("Dictionary as list",list_li,"\n")
      
    return(list_li)
    
def convert_heap(list_li):
      
    # list to hold salary values
    sal_li=[]
  
    # extrat salary values
    for i in range(0,len(list_li)):
        
        sal_li.append(list_li[i][1]['Salary'])
  
    print("Before heapify :",sal_li,"\n")
  
    # heapify the salary values
    hq.heapify(sal_li)
  
    print("After heapify :",sal_li,"\n")
  
    # list to hold the final dictionary as heap
    final=[]
  
    # reconstruction of dictionary as heap
    # yields a list of tuples of key-value pairs
    for i in range(0,len(sal_li)):
        
        for j in range(0,len(sal_li)):
            
            if list_li[j][1]['Salary']==sal_li[i]:
                final.append(list_li[j])
              
    # list of tuples to dictionary
    final=dict(final)
     
    return final
    
nested_dict={
    "emp01":{
        "name":"Kate",
        "age":22,
        "designation": "Analyst",
        "Salary":30000
    },
    "emp02":{
        "name":"Rina",
        "age":20,
        "designation":"Programmer",
        "Salary":25000
    },
    "emp03":{
        "name":"Vikas",
        "age":42,
        "designation":"Manager",
        "Salary":35000
    },
    "emp04":{
        "name":"manish",
        "age":42,
        "designation":"Manager",
        "Salary":15000
    }
}
  
list_li=get_list(nested_dict)
  
final=convert_heap(list_li)
  
print("Dictionary as heap :",final)

chevron_right


Output

Dictionary as list [(’emp01′, {‘name’: ‘Kate’, ‘age’: 22, ‘designation’: ‘Analyst’, ‘Salary’: 30000}), (’emp02′, {‘name’: ‘Rina’, ‘age’: 20, ‘designation’: ‘Programmer’, ‘Salary’: 25000}), (’emp03′, {‘name’: ‘Vikas’, ‘age’: 42, ‘designation’: ‘Manager’, ‘Salary’: 35000}), (’emp04′, {‘name’: ‘manish’, ‘age’: 42, ‘designation’: ‘Manager’, ‘Salary’: 15000})]

 Before heapify : [30000, 25000, 35000, 15000] 

 After heapify : [15000, 25000, 35000, 30000] 

Dictionary as heap : {’emp04′: {‘name’: ‘manish’, ‘age’: 42, ‘designation’: ‘Manager’, ‘Salary’: 15000}, ’emp02′: {‘name’: ‘Rina’, ‘age’: 20, ‘designation’: ‘Programmer’, ‘Salary’: 25000}, ’emp03′: {‘name’: ‘Vikas’, ‘age’: 42, ‘designation’: ‘Manager’, ‘Salary’: 35000}, ’emp01′: {‘name’: ‘Kate’, ‘age’: 22, ‘designation’: ‘Analyst’, ‘Salary’: 30000}}

Insertion in dictionary maintained as a heap

The insertion of new values can be done directly using heappush() method in the heapq module. Its syntax is as follows.

heapq . heappush ( list , new_value )

Now the list of tuples along with a new tuple can be passed to this function to add the new-key value pair.

Example :

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

import heapq as hq
  
# list of dictionaries
li_dict=[{11:121},{2:4},{5:25},{3:9}]
  
# list to hold tuples
heap_dict=[]
  
# convert each dict to tuple of (key,value)
heap_dict=[(k,v) for i in li_dict for k,v in i.items() ]
  
print("List of tuples :",heap_dict)
  
# applying heapify()
hq.heapify(heap_dict)   
  
print("After heapification :",heap_dict)
  
# reconvert to dict
final=dict(heap_dict)
  
print("Dictionary as heap :",final)
  
# add new value (1,1)
hq.heappush(heap_dict,(1,1))
  
print("After insertion & heapification",heap_dict)
  
#reconvert the result
final=dict(heap_dict)
  
print("New dictionary :",final)

chevron_right


Output:

List of tuples : [(11, 121), (2, 4), (5, 25), (3, 9)]
After heapification : [(2, 4), (3, 9), (5, 25), (11, 121)]
Dictionary as heap : {2: 4, 3: 9, 5: 25, 11: 121}
After insertion & heapification [(1, 1), (2, 4), (5, 25), (11, 121), (3, 9)]
New dictionary : {1: 1, 2: 4, 5: 25, 11: 121, 3: 9}

Another method that can be done is to have a function that heapify the dictionary and calling it after updating the dictionary. 

Example :

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

import heapq as hq
  
def heapify_dict(d):
    
      # convert to list of tuples
    li=list(dict1.items())
      
    hq.heapify(li)
      
    li=dict(li)
      
    print("Dictionary as heap :",li)
      
dict1={11:121,2:4,5:25,3:9}
  
print("Before adding new values")
heapify_dict(dict1)
  
# add new values to dictionary
dict1[4]=16
dict1[1]=1
  
print("Updated dictionary :",dict1)
  
print("After adding new values")
heapify_dict(dict1)

chevron_right


Output

Before adding new values
Dictionary as heap : {2: 4, 3: 9, 5: 25, 11: 121}
Updated dictionary : {11: 121, 2: 4, 5: 25, 3: 9, 4: 16, 1: 1}
After adding new values
Dictionary as heap : {1: 1, 2: 4, 5: 25, 3: 9, 4: 16, 11: 121}

Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :