📜  如何在Python的堆中维护字典?

📅  最后修改于: 2022-05-13 01:54:35.448000             🧑  作者: Mango

如何在Python的堆中维护字典?

先决条件:

  • 二叉堆数据结构
  • Python中的 heapq 模块
  • Python中的字典。

字典可以基于键或值在堆中维护。下面列出了要维护的约定:

  • 索引“ i ”处的键值对被认为是索引2k+12k+2处的键值对的父项。
  • 对于最小堆,父键/值必须小于其子键。
  • 对于最大堆,父键/值必须大于其子键。

例子:

本文展示了如何使用 heapq 模块在最小堆中维护字典。

普通字典作为堆

在 heapq 模块的帮助下,可以在堆结构中维护以整数/字符串为键的普通字典。但是这个模块期望传递一个列表。所以这里使用的方法是:

  1. 将键值对转换为元组列表。
  2. 将元组列表传递给heapify()函数。
  3. 再次将结果列表转换为字典。

注意:元组上的 heapify() 考虑进程的元组中的第一个元素。因此,默认情况下,字典仅基于键在堆中维护。

示例 1:基于整数的 Key

考虑一个字典,其中键是正整数,值是它们的平方。现在,这应该保存在一个堆中。

Python3
# 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)


Python3
# 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)


Python3
# 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)


Python3
# 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=[]
 
# convert 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)


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


Python3
def convert_heap(list_li):
     
    # list to hold salary values
    sal_li=[]
 
    # extract 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


Python3
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)


Python3
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=[]
 
    # extract 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)


Python3
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)


Python3
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)


输出
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}

示例 2:基于字符串的键

考虑一个以字母组合作为键和它们的编号作为值的字典。例如:“ abc”:123。这必须在堆中维护。

蟒蛇3

# 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)

输出:

示例 3:基于

这里的方法略有不同。要执行的步骤是:

  1. 提取字典中的值并附加到列表中。
  2. 将列表传递给heapify()。
  3. 基于堆化的列表值,通过迭代从原始字典重建一个新字典。

这里只有值满足堆属性,不一定是键。

例子:

蟒蛇3

# 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)
输出
Values of the dict after heapification : [4, 9, 25, 121]
Final dictionary : {2: 4, 3: 9, 5: 25, 11: 121}

字典列表作为堆

上面看到的示例基于单个字典。考虑必须作为堆维护的字典列表。使用的方法是:

  • 使用列表理解将每个字典转换成一个元组。
  • 将列表传递给heapify()。
  • 将生成的堆化元组列表转换为字典。

注意:元组上的 heapify() 考虑进程的元组中的第一个元素。因此,默认情况下,字典仅基于键在堆中维护。

例子 :

蟒蛇3

# 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=[]
 
# convert 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)
输出
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}

嵌套字典

在嵌套字典的情况下,该任务需要更多的步骤来维护堆中的字典。如果必须根据内部字典中的键来维护字典,则可以使用以下方法。

  • 将字典转换为元组列表,其中外部字典的键是 tuple[0],内部字典是 tuple[1]。
  • 将内部字典中键的值提取到列表中。
  • 在该列表上应用heapify()
  • 通过根据堆放结果对它们进行排序来重新构建新字典。

例如,将员工记录视为嵌套字典。记录显示如下:

现在让我们根据薪水值在最小堆中维护它。因此,最低工资的员工显示为第一条记录。为了更好的可读性和理解性,我们可以将代码拆分为函数。

第一步:定义将字典转换为列表的函数

蟒蛇3

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


第 2 步:定义执行堆化的函数。将元组列表作为参数。

蟒蛇3

def convert_heap(list_li):
     
    # list to hold salary values
    sal_li=[]
 
    # extract 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

第 3 步:定义字典并适当调用函数。

蟒蛇3

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)

现在把所有的代码放在一起,我们得到了一个在堆中维护的嵌套字典,基于薪水的值。

蟒蛇3

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=[]
 
    # extract 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)

输出

在字典中插入维护为堆

可以直接使用heapq模块中的heappush()方法插入新值。其语法如下。

现在可以将元组列表以及新元组传递给此函数以添加新键值对。

例子 :

蟒蛇3

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)

输出:

另一种可以做的方法是有一个函数来堆化字典并在更新字典后调用它。

例子 :

蟒蛇3

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)
输出
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}