Python編程:詳解內(nèi)置字典(dict)子類及應(yīng)用(一網(wǎng)打盡)
前言
本主要介紹Python集合模塊中幾個(gè)字典類(dict)的內(nèi)置擴(kuò)展子類的應(yīng)用場(chǎng)景和使用示例,還是結(jié)合代碼,讓你能“短平快”的來掌握這些跟dict直接關(guān)聯(lián)的子類——OrderedDict、defaultdict、userDict。
OrderedDict
Python集合模塊中的有序字典(OrderedDict)就像普通字典一樣,但是有一些與排序操作相關(guān)的額外功能。OrderedDict會(huì)記住鍵插入的順序?,F(xiàn)在它們變得不那么重要了,因?yàn)閮?nèi)置的dict類獲得了記住插入順序的能力(這種新行為在Python 3.7中得到了保證,因此OrderedDict現(xiàn)在顯得不是那么重要了)。創(chuàng)建有序字典的常規(guī)格式:
或者
這樣就創(chuàng)建并返回dict子類的實(shí)例OrderedDict對(duì)象,該子類具有專門用于重新排列字典順序的方法。本文就來簡(jiǎn)要介紹這些方法。
1)popitem(last=True):
有序字典的popitem()方法返回并刪一個(gè)(key,value)對(duì)。如果last為True,則以LIFO(后進(jìn)先出)方式返回相應(yīng)的鍵值對(duì);否則以FIFO(先進(jìn)先出)順序返回。
2)move_to_end(key, last=True):
將現(xiàn)有鍵移動(dòng)到有序字典的任意一端。如果last為True(默認(rèn)值),則將項(xiàng)移到右端;如果last為False,則移到開頭。如果key不存在會(huì)引發(fā)KeyError。
請(qǐng)看代碼:
假設(shè)我們刪除并重新插入相同的鍵到OrderedDict。它將把這個(gè)鍵放到末尾,以保持鍵的插入順序。示例如下:
運(yùn)行結(jié)果如下:
UserDict
UserDict類用作Python內(nèi)置字典(dict)對(duì)象的包裝器。對(duì)這個(gè)類的需求已經(jīng)部分被直接從dict繼承子類的能力所取代;但是,這個(gè)類更容易使用,因?yàn)榈讓幼值淇梢宰鳛閷傩栽L問。當(dāng)你希望使用一些修改過的或新功能創(chuàng)建自己的字典時(shí),可使用UserDict。其使用格式如下:
或者
此類模擬字典,其實(shí)例的內(nèi)容保存在一個(gè)常規(guī)字典中,可以通過UserDict實(shí)例的data屬性訪問該字典。如果提供了initialdata,則用此初始化data內(nèi)容;注意,實(shí)例本身不會(huì)單獨(dú)保留對(duì)initialdata的引用(非獨(dú)占),是允許它用于其他目的。
除了支持映射的方法和操作之外,UserDict實(shí)例提供以下屬性:
1)data
一個(gè)用于存儲(chǔ)UserDict類內(nèi)容的真正字典。示例如下:
輸出結(jié)果如下:
假設(shè)我們想要定義一個(gè)支持加法操作的自定義字典對(duì)象(合并兩字典)。當(dāng)我們添加自定義字典的兩個(gè)實(shí)例時(shí),我們希望得到一個(gè)包含兩個(gè)字典中所有元素的新字典。請(qǐng)記住,如果你試圖添加到Python中的常規(guī)字典,則會(huì)得到TypeError。讓我們?cè)赨serDict的幫助下實(shí)現(xiàn)它:
運(yùn)行輸出結(jié)果如下:
當(dāng)然,你還可以自己實(shí)現(xiàn)其它相關(guān)的自定義操作。
DefaultDict
Python中Dictionary類的一個(gè)常見問題是缺少鍵。當(dāng)試圖訪問字典中不存在的鍵時(shí),將會(huì)得到一個(gè)KeyError異常。所以每當(dāng)你需要訪問字典中的元素時(shí),你就必須處理這種情況。幸運(yùn)的是,Python提供了DefaultDict類。它用于為不存在的鍵提供一些默認(rèn)值且不引發(fā)KeyError。
DefaultDict是內(nèi)置dict類的子類。它覆蓋一個(gè)方法并添加一個(gè)可寫實(shí)例變量。其余的功能與dict相同。使用格式如下:
上述代碼返回一個(gè)新的類字典對(duì)象DefaultDict,它是內(nèi)置dict類的子類。
第一個(gè)參數(shù)為default_factory屬性提供初始值,默認(rèn)為None。所有剩下的參數(shù)都被當(dāng)作傳遞給dict構(gòu)造函數(shù)一樣對(duì)待,包括關(guān)鍵字參數(shù)。需要了解的是若提供該參數(shù),則須是可調(diào)用的。
DefaultDict對(duì)象除了支持標(biāo)準(zhǔn)的dict操作外,還支持以下方法屬性:
1)__missing__(key):
如果default_factory屬性為None,用鍵作為參數(shù)將引發(fā)一個(gè)KeyError異常。
如果default_factory不是None,則不帶參數(shù)調(diào)用它,則為給定的鍵提供默認(rèn)值,該值被插入到鍵的字典中并返回。
2)default_factory
DefaultDict對(duì)象支持default_factory實(shí)例變量。該屬性由__missing__()方法使用。如果存在,則從構(gòu)造函數(shù)的第一個(gè)參數(shù)開始初始化;如果不存在,則初始化為None。
運(yùn)行程序輸出結(jié)果為:
在上述代碼中,我們使用列表類型作為default_factory,更易于將包含鍵值序列對(duì)的列表組成字典。當(dāng)?shù)谝淮斡龅矫總€(gè)鍵時(shí),它還不在映射中,因此使用default_factory函數(shù)自動(dòng)創(chuàng)建一個(gè)條目,該函數(shù)返回一個(gè)空列表。然后list.append()操作將值連接到新列表。當(dāng)再次遇到鍵時(shí),查找正常進(jìn)行(返回該鍵的列表),然后list.append()操作將另一個(gè)值添加到列表中。這種技術(shù)比使用dict.setdefault()的等效技術(shù)要簡(jiǎn)單得多。
我們?cè)倏匆粋€(gè)示例:
輸出結(jié)果如下:
在上面代碼中,我們將default_factory設(shè)置為int。這使得defaultdict用于計(jì)數(shù)(就像其他語言中的bag或multiset)。
當(dāng)?shù)谝淮斡龅侥硞€(gè)字母時(shí),它就在映射中是不存在的,因此default_factory函數(shù)調(diào)用int()來提供一個(gè)默認(rèn)的0計(jì)數(shù)。然后遞增操作為每個(gè)字母建立計(jì)數(shù)。
提示:這里傳遞的int()函數(shù)默認(rèn)返回的是整數(shù)0。若想返回任意值,可以自定義個(gè)一個(gè)基于lambda的常量函數(shù)。示例代碼如下:
一言以蔽之:使用DefaultDict的好處就是可以避免KeyError異常,并進(jìn)行一些可能的特定處理。
本文小結(jié)
本文主要介紹了Python字典(dict)類相關(guān)的幾個(gè)內(nèi)置子類的應(yīng)用。這些直接相關(guān)的子類分別是OrderedDict、defaultdict、userDict等內(nèi)置子類。通過示例代碼和關(guān)聯(lián)描述,讓你更輕松掌握它們的應(yīng)用和基本規(guī)則。