Python中的heapq模塊解析
heapq堆隊(duì)列算法
這個(gè)模塊提供了堆隊(duì)列算法的實(shí)現(xiàn),也稱為優(yōu)先隊(duì)列算法。
堆是一個(gè)二叉樹,每個(gè)父節(jié)點(diǎn)的值 ≤ \le ≤ 所有孩子節(jié)點(diǎn)的值。 用數(shù)組實(shí)現(xiàn):從零開(kāi)始計(jì)數(shù),對(duì)于所有的 k ,都有 heap[k] ≤ \le ≤ heap[2k+1] 和 heap[k] ≤ \le ≤ heap[2k+2]。 最小的元素總是在根結(jié)點(diǎn):heap[0]。
heapq.heapify(x) # 將list x 轉(zhuǎn)換成堆,原地,線性時(shí)間內(nèi)。 heapq.heappush(heap, item) # 將 item 的值加入 heap 中,保持堆的不變性。 heapq.heappop(heap) #彈出并返回 heap 的最小的元素,保持堆的不變性。如果堆為空,拋出 IndexError 。使用 heap[0] ,可以只訪問(wèn)最小的元素而不彈出它。 heapq.heappushpop(heap, item) #將 item 放入堆中,然后彈出并返回 heap 的最小元素。該組合操作比先調(diào)用 heappush() 再調(diào)用 heappop() 運(yùn)行起來(lái)更有效率。 heapq.heapreplace(heap, item) #彈出并返回 heap 中最小的一項(xiàng),同時(shí)推入新的 item。堆的大小不變。如果堆為空則引發(fā) IndexError。
這個(gè)單步驟操作比 heappop() 加 heappush() 更高效,并且在使用固定大小的堆時(shí)更為適宜。 pop/push 組合總是會(huì)從堆中返回一個(gè)元素并將其替換為 item。
返回的值可能會(huì)比添加的 item 更大。 如果不希望如此,可考慮改用 heappushpop()。 它的 push/pop 組合會(huì)返回兩個(gè)值中較小的一個(gè),將較大的值留在堆中。
該模塊還提供了三個(gè)基于堆的通用功能函數(shù)。
heapq.merge(*iterables, key=None, reverse=False) #將多個(gè)已排序的輸入合并為一個(gè)已排序的輸出(例如,合并來(lái)自多個(gè)日志文件的帶時(shí)間戳的條目)。 返回已排序值的 iterator。
類似于 sorted(itertools.chain(*iterables)) 但返回一個(gè)可迭代對(duì)象,不會(huì)一次性地將數(shù)據(jù)全部放入內(nèi)存,并假定每個(gè)輸入流都是已排序的(從小到大)。
具有兩個(gè)可選參數(shù),它們都必須指定為關(guān)鍵字參數(shù)。
key 指定帶有單個(gè)參數(shù)的 key function,用于從每個(gè)輸入元素中提取比較鍵。 默認(rèn)值為 None (直接比較元素)。
reverse 為一個(gè)布爾值。 如果設(shè)為 True,則輸入元素將按比較結(jié)果逆序進(jìn)行合并。 要達(dá)成與 sorted(itertools.chain(*iterables), reverse=True) 類似的行為,所有可迭代對(duì)象必須是已從大到小排序的。
heapq.nlargest(n, iterable, key=None) #從 iterable 所定義的數(shù)據(jù)集中返回前 n 個(gè)最大元素組成的列表。 如果提供了 key 則其應(yīng)指定一個(gè)單參數(shù)的函數(shù),用于從 iterable 的每個(gè)元素中提取比較鍵 (例如 key=str.lower)。 等價(jià)于: sorted(iterable, key=key, reverse=True)[:n]。 heapq.nsmallest(n, iterable, key=None) #從 iterable 所定義的數(shù)據(jù)集中返回前 n 個(gè)最小元素組成的列表。 如果提供了 key 則其應(yīng)指定一個(gè)單參數(shù)的函數(shù),用于從 iterable 的每個(gè)元素中提取比較鍵 (例如 key=str.lower)。 等價(jià)于: sorted(iterable, key=key)[:n]。
后兩個(gè)函數(shù)在 n 值較小時(shí)性能最好。 對(duì)于更大的值,使用 sorted() 函數(shù)會(huì)更有效率。 此外,當(dāng) n==1 時(shí),使用內(nèi)置的 min() 和 max() 函數(shù)會(huì)更有效率。 如果需要重復(fù)使用這些函數(shù),請(qǐng)考慮將可迭代對(duì)象轉(zhuǎn)為真正的堆。
一、heapq 創(chuàng)建堆
import heapq
array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
heap = []
for num in array:
heapq.heappush(heap, num)
print("array:", array)
print("heap: ", heap)
heapq.heapify(array)
print("array:", array)
# array: [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
# heap: [5, 7, 21, 15, 10, 24, 27, 45, 17, 30, 36, 50]
# array: [5, 7, 21, 10, 17, 24, 27, 45, 15, 30, 36, 50]heapq 中創(chuàng)建堆的方法有兩種:
- heappush(heap, num),先創(chuàng)建一個(gè)空堆,然后將數(shù)據(jù)一個(gè)一個(gè)地添加到堆中。
- heapify(array),直接將數(shù)據(jù)列表調(diào)整成一個(gè)小頂堆。
二、堆排序
可以通過(guò)將所有值推入堆中然后每次彈出一個(gè)最小值項(xiàng)來(lái)實(shí)現(xiàn)。
def heapsort(iterable):
h = []
for value in iterable:
heappush(h, value)
return [heappop(h) for i in range(len(h))]
heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])這類似于 sorted(iterable),但與 sorted() 不同的是這個(gè)實(shí)現(xiàn)是不穩(wěn)定的。
堆元素可以為元組。 這適用于將比較值(例如任務(wù)優(yōu)先級(jí))與跟蹤的主記錄進(jìn)行賦值的場(chǎng)合:
h = [] heappush(h, (5, 'write code')) heappush(h, (7, 'release product')) heappush(h, (1, 'write spec')) heappush(h, (3, 'create tests')) heappop(h) (1, 'write spec')
先將待排序列表中的數(shù)據(jù)添加到堆中,構(gòu)造一個(gè)小頂堆,打印第一個(gè)數(shù)據(jù),可以確認(rèn)它是最小值。然后依次將堆頂?shù)闹等〕觯砑拥揭粋€(gè)新的列表中,直到堆中的數(shù)據(jù)取完,新列表就是排序后的列表。
heappop(heap),將堆頂?shù)臄?shù)據(jù)出堆,并將堆中剩余的數(shù)據(jù)構(gòu)造成新的小頂堆。
三、獲取堆中的最小值或最大值
array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] heapq.heapify(array) print(heapq.nlargest(2, array)) print(heapq.nsmallest(3, array))
四、使用heapq合并兩個(gè)有序列表
array_a = [10, 7, 15, 8]
array_b = [17, 3, 8, 20, 13]
array_merge = heapq.merge(sorted(array_a), sorted(array_b))
print("merge result:", list(array_merge))五、heapq 替換數(shù)據(jù)的方法
array_c = [10, 7, 15, 8]
heapq.heapify(array_c)
print("before:", array_c)
# 先 push 再 pop
item = heapq.heappushpop(array_c, 5)
print("after: ", array_c)
print(item)
array_d = [10, 7, 15, 8]
heapq.heapify(array_d)
print("before:", array_d)
# 先 pop 再 push
item = heapq.heapreplace(array_d, 5)
print("after: ", array_d)
print(item)到此這篇關(guān)于Python中的heapq模塊解析的文章就介紹到這了,更多相關(guān)heapq模塊解析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中字符串拼接的幾種方法及優(yōu)缺點(diǎn)對(duì)比詳解
在 Python 中,字符串拼接是常見(jiàn)的操作,Python 提供了多種方法來(lái)拼接字符串,每種方法有其優(yōu)缺點(diǎn)和適用場(chǎng)景,以下是幾種常見(jiàn)的字符串拼接方法,需要的朋友可以參考下2025-03-03
關(guān)于Python網(wǎng)絡(luò)爬蟲requests庫(kù)的介紹
這篇文章主要介紹了關(guān)于Python網(wǎng)絡(luò)爬蟲requests庫(kù),而很多時(shí)候這些數(shù)據(jù)存儲(chǔ)在網(wǎng)頁(yè)中,手動(dòng)下載需要花費(fèi)的時(shí)間太長(zhǎng),這時(shí)候我們就需要網(wǎng)絡(luò)爬蟲幫助我們自動(dòng)爬取這些數(shù)據(jù),需要的朋友可以參考下2023-04-04
用python一行代碼得到數(shù)組中某個(gè)元素的個(gè)數(shù)方法
今天小編就為大家分享一篇用python一行代碼得到數(shù)組中某個(gè)元素的個(gè)數(shù)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Python3 使用pillow庫(kù)生成隨機(jī)驗(yàn)證碼
這篇文章主要介紹了Python3 使用pillow庫(kù)生成隨機(jī)驗(yàn)證碼,需要的朋友可以參考下2019-08-08
Python中使用異常處理來(lái)判斷運(yùn)行的操作系統(tǒng)平臺(tái)方法
這篇文章主要介紹了Python中使用異常處理來(lái)判斷運(yùn)行的操作系統(tǒng)平臺(tái)方法,這個(gè)方法比較新穎,,需要的朋友可以參考下2015-01-01
Python如何高效找出序列中出現(xiàn)次數(shù)最多的元素
這篇文章主要為大家詳細(xì)介紹了Python如何高效找出序列中出現(xiàn)次數(shù)最多的元素,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-08-08

