python类静态函数和变量,heapq自定义优先级队列

可能是python的设计哲学考虑到,要避免快速而肮脏的脚本,而没有static关键字(只有类的静态方法@staticmethod),无现成的类静态变量,如果要使用,可以使用 global 来操作。


import heapq

STATIC_EID = 0

class Event:
    def __init__(self, ctime, name) -> None:
        self._ctime = ctime
        global STATIC_EID
        self._eid = STATIC_EID
        STATIC_EID += 1
        print('eid:', self._eid)
        self._name = name

    def __lt__(self, other):
        if self._ctime < other._ctime:
            return True
        elif self._ctime == other._ctime:
            if self._eid < other._eid:
                return True
            else:
                return False
        else:
            return False
    
    def call(self):
        print(self._name)


if __name__ == "__main__":
    pq = []
    heapq.heappush(pq, Event(100, 'a'))
    heapq.heappush(pq, Event(20, 'b'))
    heapq.heappush(pq, Event(100, 'c'))
    heapq.heappush(pq, Event(20, 'd'))

    heapq.heappop(pq).call()
    heapq.heappop(pq).call()
    heapq.heappop(pq).call()
    heapq.heappop(pq).call()

输出:

eid: 0
eid: 1
eid: 2
eid: 3
b
d
a
c

python中的堆排序模块heapq本身不支持自定义比较函数,可以通过重写对象的__lt__方法的方式来实现自定义比较函数。

__lt__对应<,当对象之间用<比较大小的时候,就会调用__lt__方法。同样的>会调用__gt__方法,在只重写了__lt__方法的时候,__gt__会对__lt__结果取反。但是当比较相等的时候,二者的结果是相等的。

在heapq模块的内部,上浮和下沉的比较就是通过对象的<比较实现的

def _siftdown(heap, startpos, pos):
    newitem = heap[pos]
    # Follow the path to the root, moving parents down until finding a place
    # newitem fits.
    while pos > startpos:
        parentpos = (pos - 1) >> 1
        parent = heap[parentpos]
        if newitem < parent:
            heap[pos] = parent
            pos = parentpos
            continue
        break
    heap[pos] = newitem

参考

posted @ 2021-05-19 10:15  VeyronC  阅读(277)  评论(0编辑  收藏  举报