A generic priority queue for Python

后端 未结 12 489
面向向阳花
面向向阳花 2020-12-13 03:27

I need to use a priority queue in my Python code, and:

  • am looking for any fast implementations for priority queues
  • optimally, I\'d li
12条回答
  •  渐次进展
    2020-12-13 04:16

    I can either use a (priority, object) as Charlie Martin suggests, or just implement __cmp__ for my object.

    If you want inserted objects to be prioritized by a specific rule, I found it very helpful to write a simple subclass of PriorityQueue which accepts a key-function. You won't have to insert (priority, object) tuples manually and the handling feels more natural.

    Demo of the desired behavior:

    >>> h = KeyHeap(sum)
    >>> h.put([-1,1])
    >>> h.put((-1,-2,-3))
    >>> h.put({100})
    >>> h.put([1,2,3])
    >>> h.get()
    (-1, -2, -3)
    >>> h.get()
    [-1, 1]
    >>> h.get()
    [1, 2, 3]
    >>> h.get()
    set([100])
    >>> h.empty()
    True
    >>>
    >>> k = KeyHeap(len)
    >>> k.put('hello')
    >>> k.put('stackoverflow')
    >>> k.put('!')
    >>> k.get()
    '!'
    >>> k.get()
    'hello'
    >>> k.get()
    'stackoverflow'
    

    Python 2 code

    from Queue import PriorityQueue
    
    class KeyHeap(PriorityQueue):
        def __init__(self, key, maxsize=0):            
            PriorityQueue.__init__(self, maxsize)
            self.key = key
    
        def put(self, x):
            PriorityQueue.put(self, (self.key(x), x))
    
        def get(self):
            return PriorityQueue.get(self)[1]
    

    Python 3 code

    from queue import PriorityQueue
    
    class KeyHeap(PriorityQueue):
        def __init__(self, key, maxsize=0):            
            super().__init__(maxsize)
            self.key = key
    
        def put(self, x):
            super().put((self.key(x), x))
    
        def get(self):
            return super().get()[1]
    

    Obviously, calling put will (and should!) raise an error if you try to insert an object which your key-function cannot process.

提交回复
热议问题