欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中heapq模塊的各種用法實(shí)例

 更新時(shí)間:2025年09月17日 10:26:48   作者:進(jìn)一步有進(jìn)一步的歡喜  
Python的heapq模塊提供了一組函數(shù)用于操作堆,其中所有函數(shù)都基于列表實(shí)現(xiàn),下面這篇文章主要介紹了Python中heapq模塊各種用法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

引言

Python heapq 模塊是一個(gè)處理堆數(shù)據(jù)結(jié)構(gòu)的強(qiáng)大工具。堆這種數(shù)據(jù)結(jié)構(gòu),以其獨(dú)特的二叉樹特性,在眾多算法和數(shù)據(jù)處理場(chǎng)景中扮演著關(guān)鍵角色。heapq模塊默認(rèn)實(shí)現(xiàn)的是最小堆,即父節(jié)點(diǎn)的值總是小于或等于其子節(jié)點(diǎn)的值。接下來,讓我們深入探索heapq的各種用法。

一、heapq基礎(chǔ)操作

(一)將列表轉(zhuǎn)換為堆

在實(shí)際編程中,我們常常需要將已有的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為堆,以便利用堆的特性進(jìn)行高效處理。heapq模塊提供了heapify()函數(shù),它能原地將一個(gè)列表轉(zhuǎn)換為堆結(jié)構(gòu),時(shí)間復(fù)雜度為O(n),這意味著對(duì)于大規(guī)模數(shù)據(jù)的轉(zhuǎn)換也能高效完成。

import heapq

nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
heapq.heapify(nums)
print(nums)

運(yùn)行上述代碼,輸出結(jié)果為[1, 1, 2, 3, 3, 9, 4, 6, 5, 5, 5] 。可以看到,原本無序的列表nums已成功轉(zhuǎn)換為一個(gè)最小堆,堆頂元素(即列表的第一個(gè)元素)為最小值。

(二)向堆中添加元素

向堆中添加元素是常見操作之一。heapq.heappush()函數(shù)專門用于此目的,它在保持堆性質(zhì)的前提下,將新元素添加到堆中。該操作的時(shí)間復(fù)雜度為O(log n),其中n是堆中元素的數(shù)量。這一特性使得在處理大規(guī)模堆時(shí),添加元素的操作依然高效。

import heapq

heap = [1, 3, 5]
heapq.heappush(heap, 2)
print(heap)

運(yùn)行結(jié)果為[1, 2, 5, 3] 。元素2被順利添加到堆中,且堆的最小堆性質(zhì)得以維持。

(三)從堆中移除最小元素

當(dāng)我們需要獲取并移除堆中的最小元素時(shí),heapq.heappop()函數(shù)便能派上用場(chǎng)。該函數(shù)移除并返回堆中的最小元素,同時(shí)調(diào)整堆結(jié)構(gòu)以保持堆性質(zhì),時(shí)間復(fù)雜度同樣為O(log n)。

import heapq

heap = [1, 2, 3, 4, 5]
min_value = heapq.heappop(heap)
print(min_value)
print(heap)

上述代碼輸出1[2, 4, 3, 5] 。最小元素1被成功移除并返回,堆結(jié)構(gòu)也相應(yīng)調(diào)整,新的最小元素2位于堆頂。

(四)獲取堆中的最小元素

有時(shí),我們僅需查看堆中的最小元素,而不希望對(duì)堆結(jié)構(gòu)進(jìn)行修改。此時(shí),直接訪問堆列表的第一個(gè)元素即可,因?yàn)槎训牡谝粋€(gè)元素始終是最小元素。

import heapq

heap = [1, 3, 5, 7, 9]
min_value = heap[0]
print(min_value)

輸出結(jié)果為1 ,通過這種簡(jiǎn)單方式,我們能快速獲取堆中的最小值,且不會(huì)改變堆的結(jié)構(gòu)。

二、heapq進(jìn)階用法

(一)heapq.heapreplace()的使用

heapq.heapreplace()函數(shù)將移除堆中最小元素與添加新元素這兩個(gè)操作合并為一個(gè)原子操作。它先移除堆中的最小元素,然后將指定元素添加到堆中,并返回被移除的最小元素。相較于先調(diào)用heappop()再調(diào)用heappush(),該函數(shù)能在一定程度上提高效率。

import heapq

heap = [1, 3, 5, 7]
replaced_value = heapq.heapreplace(heap, 4)
print(replaced_value)
print(heap)

運(yùn)行結(jié)果為1[3, 4, 5, 7] 。最小元素1被移除并返回,同時(shí)元素4被添加到堆中,堆結(jié)構(gòu)保持最小堆性質(zhì)。

(二)heapq.merge()合并多個(gè)已排序迭代器

在處理多個(gè)已排序的數(shù)據(jù)集時(shí),heapq.merge()函數(shù)非常實(shí)用。它能合并多個(gè)已排序的迭代器(如列表、元組等),并返回一個(gè)新的迭代器,該迭代器按升序生成所有輸入迭代器中的元素。合并過程借助堆數(shù)據(jù)結(jié)構(gòu),時(shí)間復(fù)雜度為O(N log k),其中N是所有輸入迭代器中元素的總數(shù),k是輸入迭代器的數(shù)量。

import heapq

list1 = [1, 4, 7]
list2 = [2, 5, 8]
list3 = [3, 6, 9]
merged = list(heapq.merge(list1, list2, list3))
print(merged)

上述代碼輸出[1, 2, 3, 4, 5, 6, 7, 8, 9] 。通過heapq.merge()函數(shù),三個(gè)已排序的列表被高效合并成一個(gè)新的已排序列表。

(三)heapq.nlargest()和heapq.nsmallest()獲取最值元素

heapq.nlargest()heapq.nsmallest()函數(shù)用于獲取堆或可迭代對(duì)象中的前n個(gè)最大和最小元素。這兩個(gè)函數(shù)在處理大數(shù)據(jù)集時(shí)優(yōu)勢(shì)明顯,因?yàn)樗鼈儫o需對(duì)整個(gè)數(shù)據(jù)集進(jìn)行排序,而是利用堆的特性快速定位目標(biāo)元素。

import heapq

nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
largest_three = heapq.nlargest(3, nums)
smallest_two = heapq.nsmallest(2, nums)
print(largest_three)
print(smallest_two)

運(yùn)行結(jié)果為[9, 6, 5][1, 1] 。heapq.nlargest(3, nums)返回列表nums中最大的三個(gè)元素,heapq.nsmallest(2, nums)返回最小的兩個(gè)元素。

三、heapq在實(shí)際場(chǎng)景中的應(yīng)用

(一)優(yōu)先隊(duì)列的實(shí)現(xiàn)

優(yōu)先隊(duì)列在許多算法和系統(tǒng)中至關(guān)重要,它按照元素的優(yōu)先級(jí)進(jìn)行排序,優(yōu)先級(jí)高的元素先出隊(duì)。借助heapq模塊,我們能輕松實(shí)現(xiàn)優(yōu)先隊(duì)列。將元素及其優(yōu)先級(jí)作為元組放入堆中,即可滿足優(yōu)先隊(duì)列的需求。

import heapq

class PriorityQueue:
    def __init__(self):
        self.heap = []
        self.count = 0

    def push(self, item, priority):
        heapq.heappush(self.heap, (-priority, self.count, item))
        self.count += 1

    def pop(self):
        _, _, item = heapq.heappop(self.heap)
        return item

pq = PriorityQueue()
pq.push('task1', 3)
pq.push('task2', 1)
pq.push('task3', 2)
print(pq.pop())
print(pq.pop())
print(pq.pop())

上述代碼定義了一個(gè)PriorityQueue類,使用heapq實(shí)現(xiàn)優(yōu)先隊(duì)列。push方法將任務(wù)及其優(yōu)先級(jí)添加到堆中,pop方法移除并返回優(yōu)先級(jí)最高的任務(wù)。輸出結(jié)果為task2、task3、task1,符合優(yōu)先隊(duì)列按照優(yōu)先級(jí)從高到低出隊(duì)的要求。

(二)數(shù)據(jù)流中位數(shù)的計(jì)算

在處理數(shù)據(jù)流時(shí),實(shí)時(shí)計(jì)算中位數(shù)是一個(gè)常見需求。利用heapq模塊,通過維護(hù)一個(gè)最大堆和一個(gè)最小堆,能高效地實(shí)現(xiàn)這一功能。合理分配數(shù)據(jù)流中的元素到兩個(gè)堆中,即可快速計(jì)算中位數(shù)。

import heapq

class MedianFinder:
    def __init__(self):
        self.small_heap = []  # 最大堆
        self.large_heap = []  # 最小堆

    def addNum(self, num):
        if not self.small_heap or num <= -self.small_heap[0]:
            heapq.heappush(self.small_heap, -num)
        else:
            heapq.heappush(self.large_heap, num)
        if len(self.small_heap) > len(self.large_heap) + 1:
            heapq.heappush(self.large_heap, -heapq.heappop(self.small_heap))
        elif len(self.large_heap) > len(self.small_heap):
            heapq.heappush(self.small_heap, -heapq.heappop(self.large_heap))

    def findMedian(self):
        if len(self.small_heap) == len(self.large_heap):
            return (-self.small_heap[0] + self.large_heap[0]) / 2
        else:
            return -self.small_heap[0]

mf = MedianFinder()
mf.addNum(1)
mf.addNum(2)
print(mf.findMedian())
mf.addNum(3)
print(mf.findMedian())

這段代碼定義了MedianFinder類,通過兩個(gè)堆(small_heap為最大堆,large_heap為最小堆)維護(hù)數(shù)據(jù)流。addNum方法將新元素添加到合適的堆中,并保證兩個(gè)堆的大小平衡。findMedian方法根據(jù)兩個(gè)堆的大小關(guān)系計(jì)算并返回中位數(shù)。

(三)Dijkstra算法的實(shí)現(xiàn)

Dijkstra算法是尋找加權(quán)圖中最短路徑的經(jīng)典算法,在實(shí)現(xiàn)過程中,需要高效獲取當(dāng)前距離源點(diǎn)最近的節(jié)點(diǎn)。heapq模塊提供的堆數(shù)據(jù)結(jié)構(gòu)恰好滿足這一需求,能顯著提升算法的執(zhí)行效率。

import heapq

def dijkstra(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    pq = [(0, start)]
    while pq:
        dist, current = heapq.heappop(pq)
        if dist > distances[current]:
            continue
        for neighbor, weight in graph[current].items():
            new_dist = dist + weight
            if new_dist < distances[neighbor]:
                distances[neighbor] = new_dist
                heapq.heappush(pq, (new_dist, neighbor))
    return distances

graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'C': 2, 'D': 5},
    'C': {'A': 4, 'B': 2, 'D': 1},
    'D': {'B': 5, 'C': 1}
}
start_node = 'A'
print(dijkstra(graph, start_node))

上述代碼實(shí)現(xiàn)了Dijkstra算法,利用heapq維護(hù)一個(gè)優(yōu)先隊(duì)列,每次從隊(duì)列中取出距離源點(diǎn)最近的節(jié)點(diǎn)進(jìn)行擴(kuò)展。通過這種方式,有效計(jì)算出從源點(diǎn)到圖中各個(gè)節(jié)點(diǎn)的最短距離。

四、總結(jié)

heapq模塊作為Python標(biāo)準(zhǔn)庫(kù)的重要組成部分,為開發(fā)者提供了一套高效處理堆數(shù)據(jù)結(jié)構(gòu)的工具。從基礎(chǔ)的堆創(chuàng)建、元素操作,到進(jìn)階的合并、獲取最值等功能,再到在優(yōu)先隊(duì)列、中位數(shù)計(jì)算、最短路徑算法等實(shí)際場(chǎng)景中的廣泛應(yīng)用,heapq展現(xiàn)出了強(qiáng)大的實(shí)用性和高效性。在日常編程中,尤其是處理大規(guī)模數(shù)據(jù)時(shí),合理運(yùn)用heapq模塊能夠顯著提升程序的性能,優(yōu)化代碼結(jié)構(gòu)。

到此這篇關(guān)于Python中heapq模塊各種用法的文章就介紹到這了,更多相關(guān)Python heapq模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python類繼承及super()函數(shù)使用說明

    Python類繼承及super()函數(shù)使用說明

    這篇文章主要介紹了Python類繼承及super()函數(shù)使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Qt5 實(shí)現(xiàn)主窗口狀態(tài)欄顯示時(shí)間

    Qt5 實(shí)現(xiàn)主窗口狀態(tài)欄顯示時(shí)間

    這篇文章主要介紹了Qt5 實(shí)現(xiàn)主窗口狀態(tài)欄顯示時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • python基礎(chǔ) range的用法解析

    python基礎(chǔ) range的用法解析

    這篇文章主要介紹了python基礎(chǔ) range的用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python中Union聯(lián)合類型注解的使用

    Python中Union聯(lián)合類型注解的使用

    Union類型用于定義變量、函數(shù)參數(shù)和返回值的聯(lián)合類型注解,本文主要介紹了Python中Union聯(lián)合類型注解的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-09-09
  • Python3 讀取Word文件方式

    Python3 讀取Word文件方式

    今天小編就為大家分享一篇Python3 讀取Word文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python調(diào)用Java接口實(shí)現(xiàn)互相SM2加簽驗(yàn)簽

    Python調(diào)用Java接口實(shí)現(xiàn)互相SM2加簽驗(yàn)簽

    這篇文章主要為大家詳細(xì)介紹了Python如何調(diào)用Java接口實(shí)現(xiàn)互相SM2加簽驗(yàn)簽功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2025-09-09
  • Jupyter notebook之如何快速打開ipynb文件

    Jupyter notebook之如何快速打開ipynb文件

    這篇文章主要介紹了Jupyter notebook之如何快速打開ipynb文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 學(xué)習(xí)python可以干什么

    學(xué)習(xí)python可以干什么

    在本文里我們給大家分享了關(guān)于學(xué)習(xí)python的前途以及告訴大家可以做什么,正在學(xué)習(xí)PYTHON的朋友們學(xué)習(xí)下。
    2019-02-02
  • Python元類基礎(chǔ)知識(shí)示例深度剖析

    Python元類基礎(chǔ)知識(shí)示例深度剖析

    這篇文章主要為大家介紹了Python元類基礎(chǔ)知識(shí)深度剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • python實(shí)現(xiàn)ROA算子邊緣檢測(cè)算法

    python實(shí)現(xiàn)ROA算子邊緣檢測(cè)算法

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)ROA算子邊緣檢測(cè)算法,以光學(xué)圖像為例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評(píng)論