Source code for arsenal.deathrow.prioritydict

from heapq import heapify, heappush, heappop


from arsenal.misc import deprecated

[docs]class prioritydict(dict): """Dictionary that can be used as a priority queue. Keys of the dictionary are items to be put into the queue, and values are their respective priorities. All dictionary methods work as expected. The advantage over a standard heapq-based priority queue is that priorities of items can be efficiently updated (amortized O(1)) using code as 'thedict[item] = new_priority.' The 'smallest' method can be used to return the object with lowest priority, and 'pop_smallest' also removes it. The 'sorted_iter' method provides a destructive sorted iterator. This implemented is based on: Matteo Dell'Amico's implementation http://code.activestate.com/recipes/522995-priority-dict-a-priority-queue-with-updatable-prio/ which is based on David Eppstein's implementation http://code.activestate.com/recipes/117228/ """ @deprecated('use arsenal.datastructures.heap.locator') def __init__(self, *args, **kwargs): super(prioritydict, self).__init__(*args, **kwargs) self._heap = None self._rebuild_heap() def _rebuild_heap(self): self._heap = [(v, k) for k, v in self.items()] heapify(self._heap)
[docs] def pop_smallest(self, value=False): """ Return the item with the lowest priority and remove it. Raises IndexError if the object is empty. """ # Implementation note: Since we don't eagerly remove an element when # it's priority changes, we need to filter our pops to make sure the # priority isn't stale. heap = self._heap v, k = heappop(heap) while k not in self or self[k] != v: # while `k` is stale v, k = heappop(heap) del self[k] if value: return k, v return k
# TODO: this isn't right because we're lazy about cleanup heappop pop_smallest # calls pop multiple times. # def __len__(self): # return len(self._heap) def __setitem__(self, key, val): # We are not going to remove the previous value from the heap, since # this would have a cost O(n). super(prioritydict, self).__setitem__(key, val) if len(self._heap) < 2 * len(self): heappush(self._heap, (val, key)) else: # When the heap grows larger than 2 * len(self), we rebuild it from # scratch to avoid wasting too much memory. self._rebuild_heap() setdefault = None update = None