(三)字典和集合
一、泛對映型別
1、標準庫裡的對映型別都是dict來實現的,它們有個共同的限制,只有可雜湊的資料才能作為對映裡的鍵;
2、如果一個物件是可雜湊的,那麼在這個物件的生命週期中,它的雜湊值是不變的。並且這個物件需要實現__hash__方法,
包含__qe__方法。原子不可變資料型別(str,bytes和數值型別)都是可雜湊的,frozenset也是可雜湊的。當一個元組所包含的所
有元素都是可雜湊的,它才是雜湊的。
3、一般使用者自定義的型別都是可雜湊的,雜湊值是其id值,
4、建立字典的方式
二、字典推導
三、常見的對映方法
1、用setdefault處理找不到的鍵
當d[k]查詢不到正確的鍵時,會丟擲異常,可以用d.get(key,default)來替代d[k]。如下為統計某元素出現的位置。
用setdefault簡化程式碼,只需要查詢一次,上面至少需要2次(不存在時需要3次)
三、對映的彈性鍵查詢
1、 當找不到鍵時,另一個選擇是defaultdict,返回某種預設值。如下返回空列表。
注:這種方法只會在__getitem__呼叫時發揮作用,即dd[k]時有效,使用dd.get(k)則會返回None。
2、特殊方法__missing__
在對映型別中,在__getitem__找不到鍵的時候,會自動呼叫__missing__方法。其中2中的isinstance是必需的,當鍵不存在時,防止遞迴呼叫;__contains__方法也是必需的,當呼叫k in d時會呼叫它,
但並沒有用k in dict來判斷鍵的存在,因為也會導致__contains__被遞迴呼叫,因此採用的是顯式的呼叫self.keys();在python3中,dict.keys()返回的是檢視,查詢元素速度快。在python2中返回的是列表,當
物件體積較大時,效率不高,因為需要掃描整個列表。
四、字典的變種
除了defaultdict的其他對映
OrderDict:新增鍵的時候會保持順序。
ChainMap: 容納數個不同的對映物件。
Counter: 計數
五、子類化UserDict
自定義對映時,以UserDict為基類,比以dict為基類更方便。UserDictr 的data屬性,是dict的例項。
六、不可變對映型別
types模組中引入一個MappingProxyType模組
七、集合論
1、 set或frozenset。set型別本身是不可雜湊的,但是frozenset可以,因此可以建立一個包含不同frozenset的set。
使用set的某些操作可以提高速度
2、集合的建立
(1)集合字面量{1},{1,2}。空集合set()({}為空字典)。
(2){1,2,3}字面量句法相比於set([1,2,3])更快。
(3)集合推導跟列表推導類似,不過將方括號換成了{}
七、dict和set背後
1、查詢時,dict和set的速度要快於列表;
2、字典中的散列表。散列表是稀疏陣列(總有空白元素),導致字典會佔用較大空間。當存放數量巨大的記錄時,放在元組或具名元組構成的列表中會是較好的選擇。
3、鍵查詢很快
4、鍵的次序取決於新增順序
5、往字典裡新增新鍵,可能會改變已有鍵的順序:當新增新鍵時,可能會為字典擴容,需要新建一個更大的散列表,這個過程可能會出現衝突。
6、由5知,不要同時對字典時行掃描和修改,最好分成兩步:掃描字典,放到一個新字典裡;修改原字典。
7、上述特點對集合同樣適用。