1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        高手如何在Python中使用collections模塊

        共 4340字,需瀏覽 9分鐘

         ·

        2021-06-09 02:07

        介   紹

        Python 3有許多內(nèi)置的數(shù)據(jù)結(jié)構(gòu),包括元組、字典和列表。數(shù)據(jù)結(jié)構(gòu)為我們提供了一種組織和存儲數(shù)據(jù)的方法。collections模塊能夠幫助我們高效地填充和操作數(shù)據(jù)結(jié)構(gòu)。


        在本教程中,我們將通過collections模塊中的三個(gè)類來幫助你處理元組、字典和列表。我們將使用namedtuples來創(chuàng)建帶有命名字段的元組,使用defaultdict來在字典中精確地分組信息,以及使用deque來高效地向一個(gè)類列表對象的每一邊添加元素。


        在本教程中,我們將主要處理一個(gè)魚類清單,當(dāng)在虛構(gòu)的水族箱中添加或刪除魚類時(shí),我們需要修改這些清單。


        必備條件

        要充分理解本教程,建議你熟悉元組、字典和列表數(shù)據(jù)類型(包括它們的語法),以及如何從它們中檢索數(shù)據(jù)。你可以查看這些教程,以獲得必要的背景信息:

        • 理解Python 3中的元組

        • 理解python3中的字典

        • Python 3中的理解列表


        向元組添加命名字段

        Python元組是一個(gè)不可變的,或不可改變的,有序的元素序列。元組經(jīng)常用來表示縱列數(shù)據(jù);例如,一個(gè)CSV文件中的行數(shù)或一個(gè)SQL數(shù)據(jù)庫中的行數(shù)。一個(gè)水族箱可以用一系列元組來記錄它的魚類的庫存。


        一個(gè)單獨(dú)的魚類元組:



        這個(gè)元組由三個(gè)字符串元素組成。


        雖然在某些方面很有用,但是這個(gè)元組并沒有清楚地指明它的每個(gè)字段代表什么。實(shí)際上,元素0是一個(gè)名稱,元素1是一個(gè)物種,元素2是一個(gè)飼養(yǎng)箱。


        魚類元組字段說明:



        這個(gè)表清楚地表明,該元組的三個(gè)元素都有明確的含義。


        來自collections模塊的namedtuple允許你向一個(gè)元組的每個(gè)元素添加顯式名稱,以便在你的Python程序中明確這些元素的含義。


        讓我們使用namedtuple來生成一個(gè)類,從而明確地命名魚類元組的每個(gè)元素:



        from collections import namedtuple 可以讓你的Python程序訪問namedtuple工廠函數(shù)。namedtuple()函數(shù)調(diào)用會返回一個(gè)綁定到名稱Fish的類。namedtuple()函數(shù)有兩個(gè)參數(shù):我們的新類“Fish”的期望名稱和命名元素["name"、"species”、“tank"]的一個(gè)列表。


        我們可以使用Fish類來表示前面的魚類元組:



        如果我們運(yùn)行這段代碼,我們將看到以下輸出:



        sammy是使用Fish類進(jìn)行實(shí)例化的。sammy是一個(gè)具有三個(gè)明確命名元素的元組。


        sammy的字段可以通過它們的名稱或者一個(gè)傳統(tǒng)的元組索引來訪問:



        如果我們運(yùn)行這兩個(gè)print調(diào)用,我們將看到以下輸出:



        訪問.species會返回與使用[1]訪問sammy的第二個(gè)元素相同的值。


        使用collections模塊中的namedtuple可以在維護(hù)元組(即它們是不可變的、有序的)的重要屬性的同時(shí)使你的程序更具可讀性。


        此外,namedtuple工廠函數(shù)還會向Fish實(shí)例添加幾個(gè)額外的方法。


        使用._asdict()將一個(gè)實(shí)例轉(zhuǎn)換為字典:



        如果我們運(yùn)行print,你會看到如下輸出:



        在sammy上調(diào)用.asdict()將返回一個(gè)字典,該字典會將三個(gè)字段名稱分別映射到它們對應(yīng)的值。


        大于3.8的Python版本輸出這一行的方式可能略有不同。例如,你可能會看到一個(gè)OrderedDict,而不是這里顯示的普通字典。


        備注: 在Python中,帶有前導(dǎo)下劃線的方法通常被認(rèn)為是“私有的”。但是,namedtuple提供的其他方法(如._asdict()、._make()、._replace()等)是公開的。


        在字典中收集數(shù)據(jù)

        在Python字典中收集數(shù)據(jù)通常是很有用的。collections模塊中的defaultdict可以幫助我們快速、簡潔地將信息集合到字典中。


        defaultdict絕不會引發(fā)一個(gè)KeyError。如果一個(gè)鍵不存在,defaultdict會插入并返回一個(gè)占位符值來代替:



        如果我們運(yùn)行這段代碼,我們將看到如下輸出:



        defaultdict會插入并返回一個(gè)占位符值,而不是引發(fā)一個(gè)KeyError。在本例中,我們將占位符值指定為一個(gè)列表。

        相比之下,常規(guī)字典會在缺失的鍵上引發(fā)一個(gè)KeyError:



        如果我們運(yùn)行這段代碼,我們將看到如下輸出:



        當(dāng)我們試圖訪問一個(gè)不存在的鍵時(shí),常規(guī)字典my_regular_dict會引發(fā)一個(gè)KeyError。


        defaultdict的行為與常規(guī)字典不同。defaultdict會不帶任何參數(shù)調(diào)用占位符值來創(chuàng)建一個(gè)新對象,而不是在缺失的鍵上引發(fā)一個(gè)KeyError。在本例中,是調(diào)用list()創(chuàng)建一個(gè)空列表。


        繼續(xù)我們虛構(gòu)的水族箱示例,假設(shè)我們有一個(gè)表示水族箱清單的魚類元組列表:



        水族箱中有三種魚——它們的名字、種類和飼養(yǎng)箱在這三個(gè)元組中都有指出。


        我們的目標(biāo)是按飼養(yǎng)箱組織我們的清單—我們想知道每個(gè)飼養(yǎng)箱中存在的魚的列表。換句話說,我們需要一個(gè)能將“tank-a”映射到["Jamie", "Mary"] ,并且將“tank-b”映射到["Jamie"]的字典。


        我們可以使用defaultdict來按飼養(yǎng)箱對魚進(jìn)行分組:



        運(yùn)行這段代碼,我們將看到以下輸出:



        fish_names_by_tank被聲明為一個(gè)defaultdict,它默認(rèn)會插入list()而不是引發(fā)一個(gè)KeyError。由于這保證了fish_names_by_tank中的每個(gè)鍵都將指向一個(gè)list,所以我們可以自由地調(diào)用.append()來將名稱添加到每個(gè)飼養(yǎng)箱的列表中。


        這里,defaultdict幫助你減少了出現(xiàn)未預(yù)期的KeyErrors的機(jī)會。減少未預(yù)期的KeyErrors意味著你可以用更少的行更清晰地編寫你的程序。更具體地說,defaultdict習(xí)慣用法讓你避免了手動(dòng)地為每個(gè)飼養(yǎng)箱實(shí)例化一個(gè)空列表。


        如果沒有 defaultdict, for循環(huán)體可能看起來更像這樣:



        使用常規(guī)字典(而不是defaultdict)意味著for循環(huán)體總是必須檢查fish_names_by_tank中給定的tank是否存在。只有在驗(yàn)證了fish_names_by_tank中已經(jīng)存在tank,或者已經(jīng)使用一個(gè)[]初始化了tank之后,我們才可以添加魚類名稱。


        在填充字典時(shí),defaultdict可以幫助我們減少樣板代碼,因?yàn)樗鼜牟灰l(fā)KeyError。


        使用deque有效地將元素添加到集合的任意一側(cè)

        Python列表是一個(gè)可變的,或可改變的,有序的元素序列。Python可以以常數(shù)時(shí)間向列表添加內(nèi)容(列表的長度對添加元素所需的時(shí)間沒有影響),但是在列表的開頭插入可能比較慢——隨著列表變大,插入花費(fèi)的時(shí)間也會增加。


        就大O符號而言,向列表追加元素操作是一個(gè)常數(shù)時(shí)間O(1)操作。相比之下,在列表的開頭插入元素要慢一些,其性能為O(n)。


        備注: 軟件工程師經(jīng)常使用稱為“大O”符號的東西來度量操作的性能。當(dāng)一個(gè)輸入的大小對執(zhí)行一個(gè)操作所需的時(shí)間沒有影響時(shí),我們就可以說該操作以常數(shù)時(shí)間或 O(1)(“1的大O”)運(yùn)行。正如你在上面所了解的,Python可以以常數(shù)時(shí)間性能(也稱為O(1))向列表中追加元素。


        有時(shí)候,輸入的大小會直接影響運(yùn)行一個(gè)操作所需的時(shí)間。例如,在一個(gè)Python列表的開頭插入元素時(shí),列表中的元素越多,插入操作的運(yùn)行速度越慢。大O符號使用字母n表示輸入的大小。將項(xiàng)目添加到Python列表的開頭以“線性時(shí)間”或 O(n)(“n的大O”)運(yùn)行。


        一般來說,O(1)個(gè)操作比O(n)個(gè)操作更快。


        我們可以在一個(gè)Python列表的開頭插入:



        如果我們運(yùn)行以上代碼,我們將看到如下輸出:



        列表上的.insert(index, object)方法允許我們在favorite_fish_list的開頭插入“Alice”。不過,值得注意的是,在一個(gè)列表的開頭插入項(xiàng)具有O(n)性能。隨著favorite_fish_list的長度的增長,在列表的開頭插入一個(gè)魚類的時(shí)間將成比例地增長,所需時(shí)間會越來越長。


        collections模塊中的deque(發(fā)音為“deck”)是一個(gè)類似列表的對象,它允許我們以常數(shù)時(shí)間(O(1))性能在一個(gè)序列的開頭或末尾插入項(xiàng)。


        在一個(gè)deque的開頭插入一個(gè)項(xiàng):



        運(yùn)行這段代碼,我們將看到以下輸出:



        我們可以使用一個(gè)先前存在的元素集合來實(shí)例化一個(gè)deque,在本例中,該集合是三個(gè)最喜歡的魚類名稱的一個(gè)列表。調(diào)用favorite_fish_deque’s appendleft方法允許我們以O(shè)(1)性能在我們集合的開頭插入一個(gè)項(xiàng)。O(1)性能意味著將一個(gè)項(xiàng)添加到 favorite_fish_deque 的開頭所花費(fèi)的時(shí)間并不會增加,即使favorite_fish_deque中有數(shù)以千計(jì)甚至數(shù)以百萬計(jì)的元素。


        備注: 盡管deque將條目添加到一個(gè)序列的開頭比列表更有效,但并不是deque執(zhí)行所有操作都比列表更高效。例如,訪問deque中的一個(gè)隨機(jī)項(xiàng)具有O(n)性能,但是訪問列表中的一個(gè)隨機(jī)項(xiàng)具有O(1)性能。當(dāng)需要快速地從你的集合的任意一側(cè)插入或刪除元素時(shí),請使用deque。時(shí)間性能的完整比較可以在Python的wiki上找到。


        結(jié)論

        collections模塊是Python標(biāo)準(zhǔn)庫的一個(gè)功能強(qiáng)大的部分,它允許你簡潔高效地處理數(shù)據(jù)。本教程介紹了collections模塊提供的三個(gè)類,包括namedtuple、 defaultdict和deque。


        從這里開始,你可以使用collection模塊的文檔去學(xué)習(xí)更多關(guān)于其他可用類和實(shí)用程序的信息。要廣泛地了解更多關(guān)于Python的知識,你可以閱讀Python 3教程系列中的《如何編寫代碼》。

        英文原文:https://davidmuller.github.io/posts/2020/05/08/collections-module-Python3.html
        譯者:浣熊君

        ···  END  ···


        推薦閱讀:

        樸素貝葉斯算法基礎(chǔ)原理

        理解關(guān)聯(lián)規(guī)則算法

        Python中的高效迭代庫itertools,排列組合隨便求

        萬字長文詳解|Python庫collections,讓你擊敗99%的Pythoner

        Python初學(xué)者必須吃透這69個(gè)內(nèi)置函數(shù)!

        Python字典詳解-超級完整版

        全面理解Python集合,17個(gè)方法全解,看完就夠了

        Python正則表達(dá)式入門到入魔


        掃描關(guān)注本號↓

        瀏覽 43
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            狠狠狠狠狠艹 | 豆花无码网站 | 久久久天堂国产精品女人 | 欧美性受XXX黑人XYX性爽 | 午夜精品91 | 国产无遮挡免费观看 | 久久久久久久久久久视频 | 波多野结衣三级在线 | 波多野结衣办公室电影 | 免费三级网站 |