📜  在Python中使用自定义谓词的 Heapq

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

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

输出:

因此,我们无法使用 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 模块函数可以将项目列表或元组列表作为参数。因此,有两种方法可以自定义排序过程:

  1. 将可迭代对象转换为元组/列表列表以进行比较。
  2. 编写一个覆盖 '<' 运算符的包装类。

转换为项目列表

该方法简单,可用于解决字典比较问题。字典项可以转换为元组列表,然后传递给 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)

输出:

示例 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)

输出:

上述方法可用于任何数据类型的字典。

使用包装类

考虑一个类的对象必须在最小堆中维护的情况。例如,让我们考虑一个类,它具有诸如“名称”、“名称”、“”(服务年限)、“薪水”等属性。此类的对象必须基于“ 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