最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

引言

Python heapq 模塊是一個(gè)處理堆數(shù)據(jù)結(jié)構(gòu)的強(qiáng)大工具。堆這種數(shù)據(jù)結(jié)構(gòu),以其獨(dú)特的二叉樹(shù)特性,在眾多算法和數(shù)據(jù)處理場(chǎng)景中扮演著關(guān)鍵角色。heapq模塊默認(rèn)實(shí)現(xiàn)的是最小堆,即父節(jié)點(diǎn)的值總是小于或等于其子節(jié)點(diǎn)的值。接下來(lái),讓我們深入探索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] ??梢钥吹?,原本無(wú)序的列表nums已成功轉(zhuǎn)換為一個(gè)最小堆,堆頂元素(即列表的第一個(gè)元素)為最小值。

(二)向堆中添加元素

向堆中添加元素是常見(jiàn)操作之一。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í),直接訪問(wèn)堆列表的第一個(gè)元素即可,因?yàn)槎训牡谝粋€(gè)元素始終是最小元素。

import heapq

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

輸出結(jié)果為1 ,通過(guò)這種簡(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è)新的迭代器,該迭代器按升序生成所有輸入迭代器中的元素。合并過(guò)程借助堆數(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] 。通過(guò)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(wú)需對(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è)常見(jiàn)需求。利用heapq模塊,通過(guò)維護(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類,通過(guò)兩個(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)過(guò)程中,需要高效獲取當(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ò)展。通過(guò)這種方式,有效計(jì)算出從源點(diǎn)到圖中各個(gè)節(jié)點(diǎn)的最短距離。

四、總結(jié)

heapq模塊作為Python標(biāo)準(zhǔn)庫(kù)的重要組成部分,為開(kāi)發(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 Selenium中等待設(shè)置的實(shí)現(xiàn)

    Python Selenium中等待設(shè)置的實(shí)現(xiàn)

    本文主要介紹了Python Selenium中等待設(shè)置的實(shí)現(xiàn),過(guò)詳實(shí)的示例代碼,深入介紹了顯式等待、隱式等待、自定義等待條件、多重等待條件、頁(yè)面加載狀態(tài)的等待、元素存在與可見(jiàn)性等待、Fluent等待以及異步JavaScript加載的等待,感興趣的可以了解一下
    2023-12-12
  • python+opencv+caffe+攝像頭做目標(biāo)檢測(cè)的實(shí)例代碼

    python+opencv+caffe+攝像頭做目標(biāo)檢測(cè)的實(shí)例代碼

    今天小編就為大家分享一篇python+opencv+caffe+攝像頭做目標(biāo)檢測(cè)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • python如何實(shí)現(xiàn)單向鏈表及單向鏈表的反轉(zhuǎn)

    python如何實(shí)現(xiàn)單向鏈表及單向鏈表的反轉(zhuǎn)

    這篇文章主要介紹了python如何實(shí)現(xiàn)單向鏈表及單向鏈表的反轉(zhuǎn),幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-03-03
  • python之pexpect實(shí)現(xiàn)自動(dòng)交互的例子

    python之pexpect實(shí)現(xiàn)自動(dòng)交互的例子

    今天小編就為大家分享一篇python之pexpect實(shí)現(xiàn)自動(dòng)交互的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Python網(wǎng)絡(luò)編程之網(wǎng)絡(luò)與通信介紹

    Python網(wǎng)絡(luò)編程之網(wǎng)絡(luò)與通信介紹

    這篇文章主要介紹了Python網(wǎng)絡(luò)編程之網(wǎng)絡(luò)與通信介紹,計(jì)算機(jī)網(wǎng)絡(luò)就是分布在不同的地區(qū)的計(jì)算機(jī)與專門的外部設(shè)備通信線路互聯(lián)在一起,
    成為一個(gè)功能強(qiáng),規(guī)模大的網(wǎng)絡(luò)系統(tǒng),本期就主要介紹網(wǎng)絡(luò)與通信的相關(guān)知識(shí)和原理,需要的朋友可以參考下
    2023-08-08
  • 深入講解Python中面向?qū)ο缶幊痰南嚓P(guān)知識(shí)

    深入講解Python中面向?qū)ο缶幊痰南嚓P(guān)知識(shí)

    這篇文章主要介紹了深入講解Python中面向?qū)ο缶幊痰南嚓P(guān)知識(shí),是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-05-05
  • django雙下劃線的具體使用

    django雙下劃線的具體使用

    雙下劃線約定通常用于執(zhí)行一些特定的查詢操作,本文主要介紹了django雙下劃線的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • Python正則獲取、過(guò)濾或者替換HTML標(biāo)簽的方法

    Python正則獲取、過(guò)濾或者替換HTML標(biāo)簽的方法

    這篇文章主要介紹了Python通過(guò)正則表達(dá)式獲取、過(guò)濾或者替換HTML標(biāo)簽的方法,感興趣的小伙伴們可以參考一下
    2016-01-01
  • pytorch和tensorflow計(jì)算Flops和params的詳細(xì)過(guò)程

    pytorch和tensorflow計(jì)算Flops和params的詳細(xì)過(guò)程

    這篇文章主要介紹了pytorch和tensorflow計(jì)算Flops和params,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Pytorch中torchtext終極安裝方法以及常見(jiàn)問(wèn)題

    Pytorch中torchtext終極安裝方法以及常見(jiàn)問(wèn)題

    torchtext是pytorch框架中用于文本處理的,下面這篇文章主要給大家介紹了關(guān)于Pytorch中torchtext終極安裝方法以及常見(jiàn)問(wèn)題的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05

最新評(píng)論

玉树县| 梓潼县| 柏乡县| 察雅县| 浠水县| 正安县| 喀什市| 德庆县| 尉犁县| 大埔县| 宿松县| 西安市| 枣阳市| 金阳县| 壤塘县| 营山县| 岳池县| 清镇市| 博兴县| 兰考县| 明水县| 丰原市| 廊坊市| 北川| 阆中市| 横峰县| 汨罗市| 长春市| 兴义市| 武清区| 盐源县| 门头沟区| 定州市| 巩义市| 文化| 和田市| 无棣县| 怀仁县| 临邑县| 三穗县| 杂多县|