当我使用heapq.heappop(queue)时,会弹出列表中的第一个项目,但会修改剩余的列表。我怎么能阻止这个? (注意下面包含'r'和'o'的元组)
这是我的调试输出:
队列:PQ:[(1,2,'z'),(1,3,'t'),(2,4,'r'),(2,5,'o'),(2 ,6,'f')]
Pop之前的队列:[(1,2,'z'),(1,3,'t'),(2,4,'r'),(2,5,'o'),(2 ,6,'f')]
priority, counter, node = heapq.heappop(queue)
项目返回:(1,2,'z') 流行后的队列:[(1,3,'t'),(2,5,'o'),(2,4,'r'),(2,6,'f')]
计数器应该确保先前添加的节点更靠近队列[0]。
pop之后的队列不只是弹出堆[0],它重新排列并在包含'r'的元组之前放置包含'o'的元组。它们的优先级相同(2),但它们的计数器分别为5和4,因此,它们按错误的顺序重新排列。
Inst heappop()只假设返回堆[0]并将所有其他内容移到队列中?我怎样才能防止这种重新排列?
答案 0 :(得分:2)
这是堆的正常预期行为。堆的任意元素之间没有隐含的排序:唯一的不变量是每个节点都小于其子节点。弹出(1,3,'t')
元素后,(2,4,'r')
将被选为新根,因为它是前根的两个孩子中较小的一个;相对于(2,5,'o')
的排序在该时间点之前无关紧要。换句话说,root是唯一的元素,你可以根据它在堆中的索引来说明它的值。
如果您希望列表始终按完全排序顺序排列,则需要bisect
模块,而不是heapq
。当然,表现会更差。