Python使用heapq實現小頂堆(TopK大)、大頂堆(BtmK小)


Python使用heapq實現小頂堆(TopK大)、大頂堆(BtmK小) | 四號程序員

Python使用heapq實現小頂堆(TopK大)、大頂堆(BtmK小)

需1求:給出N長的序列,求出TopK大的元素,使用小頂堆,heapq模塊實現。

01 import heapq
02 import random
03  
04 class TopkHeap(object):
05     def __init__(self, k):
06         self.k = k
07         self.data = []
08  
09     def Push(self, elem):
10         if len(self.data) < self.k:
11             heapq.heappush(self.data, elem)
12         else:
13             topk_small = self.data[0]
14             if elem > topk_small:
15                 heapq.heapreplace(self.data, elem)
16  
17     def TopK(self):
18         return [x for x in reversed([heapq.heappop(self.data) for x in xrange(len(self.data))])]
19  
20 if __name__ == "__main__":
21     print "Hello"
22     list_rand = random.sample(xrange(1000000), 100)
23     th = TopkHeap(3)
24     for i in list_rand:
25         th.Push(i)
26     print th.TopK()
27     print sorted(list_rand, reverse=True)[0:3]

上面的用heapq就能輕松搞定。

變態的需求來了:給出N長的序列,求出BtmK小的元素,即使用大頂堆。

heapq在實現的時候,沒有給出一個類似Java的Compartor函數接口或比較函數,開發者給出了原因見這里:http://code.activestate.com/lists/python-list/162387/

於是,人們想出了一些很NB的思路,見:http://stackoverflow.com/questions/14189540/python-topn-max-heap-use-heapq-or-self-implement

我來概括一種最簡單的:

將push(e)改為push(-e)、pop(e)改為-pop(e)。

也就是說,在存入堆、從堆中取出的時候,都用相反數,而其他邏輯與TopK完全相同,看代碼:

01 class BtmkHeap(object):
02     def __init__(self, k):
03         self.k = k
04         self.data = []
05  
06     def Push(self, elem):
07         # Reverse elem to convert to max-heap
08         elem = -elem
09         # Using heap algorighem
10         if len(self.data) < self.k:
11             heapq.heappush(self.data, elem)
12         else:
13             topk_small = self.data[0]
14             if elem > topk_small:
15                 heapq.heapreplace(self.data, elem)
16  
17     def BtmK(self):
18         return sorted([-x for x in self.data])

經過測試,是完全沒有問題的,這思路太Trick了……


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM