1. 程式人生 > >(三)字典和集合

(三)字典和集合

 一、泛對映型別

       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、上述特點對集合同樣適用。