dict、defaultdict 和 OrderedDict 比較
一.dict、defaultdict 和 OrderedDict 常見的方法比較
dict | defaultdict | OrderdDict | 方法作用 | |
d.clear() | √ | √ | √ | 移除所有元素 |
d.__contains__(k) | √ | √ | √ | 檢查 k 是否在 d 中 |
d.copy() | √ | √ | √ | 淺復制 |
d.__copy__() | √ | 用於支持 copy.copy | ||
.default_factory | √ |
在 __missing__ 函數中被調用的 |
||
d.__delitem__(k) | √ | √ | √ | del d[k],移除鍵為 k 的元素 |
d.fromkeys(it, |
√ | √ | √ |
將叠代器 it 裏的元素設置為映射 就把它作為這些鍵對應的值(默 認是 None) |
d.get(k,[default]) | √ | √ | √ | 返回鍵 k 對應的值,如果字典裏
沒有鍵 k,則返回 None 或者 |
d.__getitem__(k) | √ | √ | √ |
讓字典 d 能用 d[k] 的形式返回鍵 |
d.items() | √ | √ | √ | 返回 d 裏所有的鍵值對 |
d.__iter__() | √ | √ | √ | 獲取鍵的叠代器 |
d.keys() | √ | √ | √ | 獲取所有的鍵 |
d.__len__() | √ | √ | √ |
可以用 len(d) 的形式得到字典裏 |
d.__missing__(k) | √ |
當 __getitem__ 找不到對應鍵的 |
||
d.move_to_end(k, |
√ |
把鍵為 k 的元素移動到最靠前或 |
||
d.pop(k, [defaul] | √ | √ | √ |
返回鍵 k 所對應的值,然後移除 |
d.popitem() | √ | √ | √ |
隨機返回一個鍵值對並從字典裏 |
d.__reversed__() | √ | 返回倒序的鍵的叠代器 | ||
d.setdefault(k, |
√ | √ | √ |
若字典裏有鍵k,則把它對應的值 |
d.__setitem__(k, |
√ | √ | √ |
實現 d[k] = v 操作,把 k 對應的 |
d.update(m, |
√ | √ | √ |
m 可以是映射或者鍵值對叠代 |
d.values() | √ | √ | √ | 返回字典裏的所有值 |
註:1.default_factory 並不是一個方法,而是一個可調用對象(callable),它的值在defaultdict 初始化的時候由用戶設定。
2.OrderedDict.popitem() 會移除字典裏最先插入的元素(先進先出);同時這個方法還有一個可選的 last 參數,若為真,則會移除最後插入的元素(後進先出)(而dict和defaultdict則是隨機移除);
3.dict.keys()在Python3中的返回值是一個“視圖”。視圖就像一個集合,而且跟字典類似的是,在視圖裏查找一個元素的速度很快;Python2中返回的是一個列表,查詢慢。
二.映射的彈性查詢
有時候為了方便起見,就算某個鍵在映射裏不存在,我們也希望在通過這個鍵讀取值的時候能得到一個默認值。有兩個途徑能幫我們達到這個目的,一個是通過 defaultdict 這個類型而不是普通的 dict,另一個是給自己定義一個 dict 的子類,然後在子類中實現 __missing__ 方法。
1.collections.defaultdict:
步驟:
(1) 調用 list() 來建立一個新列表。
(2) 把這個新列表作為值,‘new-key‘ 作為它的鍵,放到 dd 中。
(3) 返回這個列表的引用。而這個用來生成默認值的可調用對象存放在名為 default_factory 的實例屬性裏。
註:defaultdict 裏的 default_factory 只會在__getitem__ 裏被調用,在其他的方法裏完全不會發揮作用。比如,dd 是個 defaultdict,k 是個找不到的鍵, dd[k] 這個表達式會調用 default_factory 創造某個默認值,而 dd.get(k) 則會返回 None。
2.__miss__方法:
如果一個類繼承了dict,且實現了__miss__()方法,則在調用__getitem__()方法找不到鍵時(即d["test"]沒有這個鍵)不會直接拋出KeyError。
3.collections.OrderedDict和collections.ChainMap和collections.Counter:
3.1collections.OrderedDict:
這個類型在添加鍵的時候會保持順序,因此鍵的叠代次序總是一致的。
3.2collections.ChainMap:
該類型可以容納數個不同的映射對象,然後在進行鍵查找操作的時候,這些對象會被當作一個整體被逐個查找,直到鍵被找到為止。
3.3collections.Counter:
這個映射類型會給鍵準備一個整數計數器。每次更新一個鍵的時候都會增加這個計數器。一般用做計數。
4.如果要自定義映射類型,一般不會直接繼承dict,而是繼承collections.UserDict 類:
傾向於從 UserDict 而不是從 dict 繼承的主要原因是,後者有時會在某些方法的實現上走一些捷徑,導致我們不得不在它的子類中重寫這些方法,但是 UserDict 就不會帶來這些問題。內置類型的方法不會調用子類覆蓋的方法。例如,dict 的子類覆蓋的 __getitem__() 方法不會被內置類型的get() 方法調用等。
註:
UserDict 並不是 dict 的子類,但是UserDict 有一個叫作 data 的屬性,是 dict 的實例,這個屬性實際上是 UserDict 最終存儲數據的地方。這樣做的好處是,UserDict 的子類就能在實現 __setitem__ 的時候避免不必要的遞歸,也可以讓 __contains__ 裏的代碼更簡潔。
dict、defaultdict 和 OrderedDict 比較