我尝试使用python3.5标准库中的heappq模块来为相同类型的对象建立一个优先级队列。我希望能够基于对象的属性进行修复,然后更改其中一些属性的值,然后根据新值重新进行修复。我在想我该怎么做。在
import heappq
class multiNode:
def __init__(self, keyValue):
self.__key = keyValue
def setKey(self, keyValue):
self.__key = keyValue
def getKey(self):
return self.__key
queue = [multiNode(1), multiNode(2), multiNode(3)]
heapq.heapify(queue) #want to heapify by whatever getKey returns for each node
queue[0].setKey(1000)
heapq.heapify(queue) #re heapify with those new values
有多种方法可以使代码工作。例如,您可以通过实现一些rich comparison operator methods(也许可以使用^{} 来实现其余的)来使您的项可排序:
这将使您的代码正常工作,但在每次更改队列中的某个节点时,尤其是在队列中有很多节点的情况下,重新初始化队列可能不是很有效。一个更好的方法可能是在队列周围编写一些额外的逻辑,这样就可以使队列条目无效,而不会删除它或违反heap属性。然后,当您有一个需要更新的项时,您只需使它的旧条目无效,并添加一个具有新优先级的新条目。在
下面是一个快速而肮脏的实现,它使用字典将节点实例映射到
^{pr2}$[pritority, node]
列表。如果节点正在更新其优先级,则检查字典并将列表的node
部分设置为None
。当从队列前面弹出节点时,将忽略无效的条目。在您可能需要在重新确认时对此进行测试,以确定程序实际使用队列的速度更快。在
关于您的
multiNode
类的最后几点注释(与您在问题中所问的内容无关):你在课堂上做的很多事情都不是很像Python。首先,Python最常见的命名约定是将
CapitalizedNames
用于类,lower_case_names_with_underscores
用于几乎所有其他东西(各种变量、函数、模块)。在对
__key
使用双前导下划线的另一个问题。双前导(而不是尾随)undescrores调用Python的名称混乱系统。这看起来似乎是为了让变量私有化,但实际上并非如此。它更倾向于帮助防止意外的名称冲突,例如在代理对象(在其他情况下模仿其他对象的属性)或mixin类(可能由具有未知属性的其他类型继承)中设置属性时。如果类外的代码确实想访问您的multiNode
类中损坏的属性__key
,那么它们仍然可以通过使用_multiNode__key
来实现。要暗示某个有意为私有属性,您只需使用一个下划线_key
。在这让我想到了我的最后一期,那}和{}!在
key
可能根本不应该是私人的。使用getX
和setX
方法修改私有实例变量并不是很像python。更常见的做法是记录属性是类的公共API的一部分,并让其他代码直接访问它。如果以后决定在查找或修改属性时需要执行一些特别的操作,可以使用property
描述符自动将属性访问转换为对getter和setter函数的调用。其他编程语言通常以getter和setter开始,而不是公共属性,因为以后没有这种方法可以更改属性API的实现。所以不管怎样,我会让你的类的__init__
只设置self.key = keyValue
并完全删除{一种简单的方法是使用
dicts
和Python内置的id()
方法。这个方法基本上允许您将堆作为您创建的对象的id
的堆,然后通过在dict
中访问它们来更新这些对象,其中它们的id
是键。我在我的本地机器上试过了,它似乎能满足您的要求:heapify()
在这里不会做太多,因为对象的id
在被删除之前都是相同的。如果要向堆中添加新对象并取出对象,则此方法更有用。在相关问题 更多 >
编程相关推荐