Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:更新heapq中元素的值_Python_Python 2.7_Queue_Heap_Priority Queue - Fatal编程技术网

Python:更新heapq中元素的值

Python:更新heapq中元素的值,python,python-2.7,queue,heap,priority-queue,Python,Python 2.7,Queue,Heap,Priority Queue,如果我有一个包含以下元素的heapq: import heapq class Element(object): def __init__(self, name, val): self.name = name self.val = val if __name__ == "__main__": heap = [] e1 = Element('A', 1) e2 = Element('B', 65) e3 = Element

如果我有一个包含以下元素的heapq:

import heapq


class Element(object):
    def __init__(self, name, val):
        self.name = name
        self.val = val

if __name__ == "__main__":
    heap = []
    e1 = Element('A', 1)
    e2 = Element('B', 65)
    e3 = Element('C', 53)
    e4 = Element('D', 67)
    ...

    heapq.heappush(heap, e1)
    heapq.heappush(heap, e2)
    heapq.heappush(heap, e3)
    heapq.heappush(heap, e4)
    ...

    #IF I want to take elements from the heap and print them I will call:
    while heap:
        new_e = heapq.heappop(heap)
        print new_e.name + ' ' + str(new_e.val)
假设堆上有50个元素。我想把元素e3的值从val=53改为val=0。所以这不是堆的顶部元素。我也不想从堆中删除其他元素。
如何进行此类更新?

由于没有输出,运行代码很困难。但是,我尝试了一些方法:

在heapq模块中,
heap[0]
始终被指定为最小项。在您的情况下,1是最小的项。因此,从理论上讲,将该值从1更改为5应该很容易。我尝试了
heapq.heappop(heap)
,它应该返回最小的值。因此,正如您在问题中所说,“我想更新元素的val,我不知道它是哪一个”,此方法会自动获取最小值(根据您的问题,我假设您希望替换1,因为它是最小值,因为它与名称
First
)相结合,当我尝试自己运行您的代码时,我收到了
,因此您应该尝试修复您的代码,以便可以打印输出,
打印堆[0]
,同样的错误类型。然后,一旦不再收到此类错误,请在代码块末尾尝试:

s = heapq.heappop(heap)

print heapq.heapreplace(5, s)
使用这种方法,我得到以下错误:
TypeError:heap参数必须是一个列表
因此,如果您能够找出如何将s转换为列表,那么这应该是可行的。也许有人可以编辑我的答案来添加此代码

希望这有帮助

自我编辑:

将其添加到代码块的末尾,[]将其转换为列表,这是heapq想要的输入

s = heapq.heappop(heap)

print heapq.heapreplace([5], [s])
这将返回输出中的值5


回到输出问题,如果您指定希望输出的外观,我可以尝试为您提供更多帮助。

这是一个老问题,但万一将来有人看到这一点并正在寻找答案

针对Python3的heapq的新实现包括一些关于如何更新堆元素的有用说明,本质上是将其用作优先级队列。 本质上,您可以创建一堆元组,Python将基于元组的顺序比较来评估优先级。由于Python中的堆基本上只是一个标准列表,上面使用了heapq接口,因此文档建议可能有一个额外的字典,将堆值映射到堆中的索引(列表)

那么对于你最初的问题:

假设堆上有50个元素。我想改变这个值 元素e3的值从val=53到val=0。所以这不是最重要的元素 一堆的。我也不想从堆中删除其他元素。 我怎样才能做这样的更新

按照上述逻辑更新堆中元素的基本步骤如下:

  • 检查dictionary以获取要更新的元素的索引(在检查元素是否位于dictionary+相应堆中之后)
  • 更新堆中的值
  • 调用在O(N)中运行的heapq.heapify(heap)。或者,如果您知道您的更新将更新+/-1的值,那么您可能只需将您尝试更新的元素的位置与其上方或下方的元素交换即可

编辑:这里有一个类似的问题,有更多的答案:

使用
heapq
创建具有更新的优先级队列的可能解决方案是。您的
元素
不可比较,因此我不确定如何将它们与
heapq
一起使用。你需要一个
\uu lt\uuu
方法(或者使用一个内置类型,比如
tuple
,它已经是可比较的)。哦,我明白了,在Python 2中,所有对象都是可比较的,只要不定义
\uu cmp\uuu
或一些丰富的比较方法,就可以任意排序。尽管如此,这个问题还是有点荒谬,因为
元素
实例的
val
属性与它在堆中的位置没有任何关系。您误解了我的问题。我做了一个编辑来更好地解释我的问题,并且我还试图展示我如何打印有关元素的信息。代码运行良好。关于“调用在O(N)中运行的heapq.heapify(heap)”:重新平衡只需要O(logn)或树的最大深度,这个过程有点像您建议的交换父/子位置。但是,如果在某些情况下没有错误,“将值更新+/-1”是误导性的。特别是,如果优先级值不必是唯一的,或者优先级值不是整数,比如浮点数,这是错误的。