在Python中使用自定义谓词的 Heapq
先决条件: heapq 模块
heapq 模块有几个函数,它们将列表作为参数并按最小堆顺序排列。这些函数的问题在于它们需要一个列表或一个元组列表作为参数。它们不支持任何其他可迭代对象或对象之间的比较。例如,考虑一个必须在堆中维护的字典。
Python3
import heapq as hq
my_dict={'a':'apple', 'b':'ball', 'c': 'cat'}
hq.heapify(my_dict)
print(my_dict)
Python3
import heapq as hq
my_dict=[{'a':'apple'}, {'b':'ball'}, {'c': 'cat'}]
hq.heapify(my_dict)
print(my_dict)
Python3
#import module
import heapq as hq
# the dictionary to be as heap
my_dict = {'z': 'zebra', 'b': 'ball', 'w': 'whale',
'a': 'apple', 'm': 'monkey', 'c': 'cat'}
# conversion to tuple
my_list = [(k, v) for k, v in my_dict.items()]
print("Before organizing as heap :", my_list)
# arrange as min-heap
hq.heapify(my_list)
print("After organizing as heap :", my_list)
# re convert to dictionary
my_dict = dict(my_list)
print("Resultant dictionary :", my_dict)
Python3
#import module
import heapq as hq
# the dictionary to be as heap
my_dict = {'z': 'zebra', 'b': 'ball', 'w': 'whale',
'a': 'apple', 'm': 'monkey', 'c': 'cat'}
# conversion to tuple
my_list = [(k, v) for k, v in my_dict.items()]
print("Before organizing as heap :", my_list)
# arrange as min-heap
hq.heapify(my_list)
print("After organizing as heap :", my_list)
# re convert to dictionary
my_dict = dict(my_list)
print("Resultant dictionary :", my_dict)
Python3
#import module
import heapq as hq
# the list of dictionaries to be as heap
my_dict = [{'z': 'zebra'}, {'b': 'ball'}, {'w': 'whale'},
{'a': 'apple'}, {'m': 'monkey'}, {'c': 'cat'}]
# conversion to tuple
my_list = [(k, v) for i in my_dict for k, v in i.items()]
print("Before organizing as heap :", my_list)
# arrange as min-heap
hq.heapify(my_list)
print("After organizing as heap :", my_list)
# re convert to dictionary
my_dict = dict(my_list)
print("Resultant dictionary :", my_dict)
Python3
# import required module
import heapq as hq
# class definition
class employee:
# constructor
def __init__(self, n, d, yos, s):
self.name = n
self.des = d
self.yos = yos
self.sal = s
# function for customized printing
def print_me(self):
print("Name :", self.name)
print("Designation :", self.des)
print("Years of service :", str(self.yos))
print("salary :", str(self.sal))
# override the comparison operator
def __lt__(self, nxt):
return self.yos < nxt.yos
# creating objects
e1 = employee('Anish', 'manager', 3, 24000)
e2 = employee('kathy', 'programmer', 2, 15000)
e3 = employee('Rina', 'Analyst', 5, 30000)
e4 = employee('Vinay', 'programmer', 1, 10000)
# list of employee objects
emp = [e1, e2, e3, e4]
# converting to min-heap
# based on yos
hq.heapify(emp)
# printing the results
for i in range(0, len(emp)):
emp[i].print_me()
print()
输出
TypeError: heap argument must be a list
heapify()函数期望参数是一个列表。所以如果我们考虑一个字典列表,看看下面会发生什么。
蟒蛇3
import heapq as hq
my_dict=[{'a':'apple'}, {'b':'ball'}, {'c': 'cat'}]
hq.heapify(my_dict)
print(my_dict)
输出:
TypeError: ‘<‘ not supported between instances of ‘dict’ and ‘dict’
因此,我们无法使用 heapq 模块比较两个字典。有时我们可能需要比较一个类的对象并将它们保存在一个堆中。此类对象之间的比较对于此模块也是不可行的。
蟒蛇3
#import module
import heapq as hq
# the dictionary to be as heap
my_dict = {'z': 'zebra', 'b': 'ball', 'w': 'whale',
'a': 'apple', 'm': 'monkey', 'c': 'cat'}
# conversion to tuple
my_list = [(k, v) for k, v in my_dict.items()]
print("Before organizing as heap :", my_list)
# arrange as min-heap
hq.heapify(my_list)
print("After organizing as heap :", my_list)
# re convert to dictionary
my_dict = dict(my_list)
print("Resultant dictionary :", my_dict)
本文讨论如何克服上述问题。
自定义heapq中的排序
heapq 模块函数可以将项目列表或元组列表作为参数。因此,有两种方法可以自定义排序过程:
- 将可迭代对象转换为元组/列表列表以进行比较。
- 编写一个覆盖 '<' 运算符的包装类。
转换为项目列表
该方法简单,可用于解决字典比较问题。字典项可以转换为元组列表,然后传递给 heapify 方法。
示例 1:一个简单的字典
蟒蛇3
#import module
import heapq as hq
# the dictionary to be as heap
my_dict = {'z': 'zebra', 'b': 'ball', 'w': 'whale',
'a': 'apple', 'm': 'monkey', 'c': 'cat'}
# conversion to tuple
my_list = [(k, v) for k, v in my_dict.items()]
print("Before organizing as heap :", my_list)
# arrange as min-heap
hq.heapify(my_list)
print("After organizing as heap :", my_list)
# re convert to dictionary
my_dict = dict(my_list)
print("Resultant dictionary :", my_dict)
输出:
Before organizing as heap : [(‘z’, ‘zebra’), (‘b’, ‘ball’), (‘w’, ‘whale’), (‘a’, ‘apple’), (‘m’, ‘monkey’), (‘c’, ‘cat’)]
After organizing as heap : [(‘a’, ‘apple’), (‘b’, ‘ball’), (‘c’, ‘cat’), (‘z’, ‘zebra’), (‘m’, ‘monkey’), (‘w’, ‘whale’)]
Resultant dictionary : {‘a’: ‘apple’, ‘b’: ‘ball’, ‘c’: ‘cat’, ‘z’: ‘zebra’, ‘m’: ‘monkey’, ‘w’: ‘whale’}
示例 2:字典列表
蟒蛇3
#import module
import heapq as hq
# the list of dictionaries to be as heap
my_dict = [{'z': 'zebra'}, {'b': 'ball'}, {'w': 'whale'},
{'a': 'apple'}, {'m': 'monkey'}, {'c': 'cat'}]
# conversion to tuple
my_list = [(k, v) for i in my_dict for k, v in i.items()]
print("Before organizing as heap :", my_list)
# arrange as min-heap
hq.heapify(my_list)
print("After organizing as heap :", my_list)
# re convert to dictionary
my_dict = dict(my_list)
print("Resultant dictionary :", my_dict)
输出:
Before organizing as heap : [(‘z’, ‘zebra’), (‘b’, ‘ball’), (‘w’, ‘whale’), (‘a’, ‘apple’), (‘m’, ‘monkey’), (‘c’, ‘cat’)]
After organizing as heap : [(‘a’, ‘apple’), (‘b’, ‘ball’), (‘c’, ‘cat’), (‘z’, ‘zebra’), (‘m’, ‘monkey’), (‘w’, ‘whale’)]
Resultant dictionary : {‘a’: ‘apple’, ‘b’: ‘ball’, ‘c’: ‘cat’, ‘z’: ‘zebra’, ‘m’: ‘monkey’, ‘w’: ‘whale’}
上述方法可用于任何数据类型的字典。
使用包装类
考虑一个类的对象必须在最小堆中维护的情况。例如,让我们考虑一个类,它具有诸如“名称”、“名称”、“哟”(服务年限)、“薪水”等属性。此类的对象必须基于“ yos ”(服务年限)在最小堆中维护。
在这里,我们覆盖了关系运算符“ < ”,以便它比较每个员工的服务年数并返回 true 或 false。根据返回的布尔值,heapq 模块按最小堆顺序排列对象。
蟒蛇3
# import required module
import heapq as hq
# class definition
class employee:
# constructor
def __init__(self, n, d, yos, s):
self.name = n
self.des = d
self.yos = yos
self.sal = s
# function for customized printing
def print_me(self):
print("Name :", self.name)
print("Designation :", self.des)
print("Years of service :", str(self.yos))
print("salary :", str(self.sal))
# override the comparison operator
def __lt__(self, nxt):
return self.yos < nxt.yos
# creating objects
e1 = employee('Anish', 'manager', 3, 24000)
e2 = employee('kathy', 'programmer', 2, 15000)
e3 = employee('Rina', 'Analyst', 5, 30000)
e4 = employee('Vinay', 'programmer', 1, 10000)
# list of employee objects
emp = [e1, e2, e3, e4]
# converting to min-heap
# based on yos
hq.heapify(emp)
# printing the results
for i in range(0, len(emp)):
emp[i].print_me()
print()
Name : Vinay
Designation : programmer
Years of service : 1
salary : 10000
Name : kathy
Designation : programmer
Years of service : 2
salary : 15000
Name : Rina
Designation : Analyst
Years of service : 5
salary : 30000
Name : Anish
Designation : manager
Years of service : 3
salary : 24000