dict類型是python語言的基石,因此python對於dict類型實現了高度優化,而 散列表 則是字典類型性能突出的根本緣由。python
定義:若是一個對象是可散列的,那麼在這個對象的生命週期中,它的散列值是始終不變的,並且這個對象一定實現__hash__()方法。 另外,可散列對象還必須實現 __eq__()方法,這樣才能保證兩個相同類型的對象能夠進行比較。若是兩個對象是相同的,那麼它們的散列值必定是相同的。app
也就是說,一個可散列對象必須同時知足如下三個條件:性能
下例展現了建立字典的不一樣方式優化
>>> d1 = dict(one=1, two=2, three=3) >>> d2 = {'one':1, 'two':2, 'three':3} >>> d3 = dict(zip(['one', 'two', 'three'], [1,2,3])) >>> d4 = dict([('two', 2), ('one', 1), ('three', 3)]) >>> d5 = dict({'one':1, 'two':2, 'three':3}) >>> d1 == d2 == d3 == d4 == d5 True
假設有一個字典dict,當程序試圖查找一個不存在的鍵值 dict[k] 時,會拋出一個異常KeyError,這個行爲複合python所信奉的「快速失敗」哲學。固然,咱們能夠採用dict.get(k, default)來代替dict[k],當找不到鍵k時,返回默認值default,可是,這並非一個高效的方式,也不是一個可取的方法。code
下面是一個案例:對象
dict_demo = {} print(dict_demo) key = "name" dict_demo.get(key) dict_demo.setdefault(key, []) print(dict_demo) dict_demo.setdefault("pass", "123456") print(dict_demo)
運行結果以下:three
{} {'name': []} {'name': [], 'pass': '123456'}
代碼中第一個 setdefault 中未找到 key,因而把一個空列表賦值到該鍵值生命週期
第二個 setdefault 未找到鍵"pass",將一個字符串賦值給該鍵ip
通過兩個setdefault以後,該字典含有兩個鍵值對,該方法主要用於對字典進行更新字符串
在用戶建立defaultdict對象時,須要給它配置一個爲找不到的鍵創造默認值的方法
具體而言,就是在實例化一個defaultdict對象時,須要給構造方法賦予一個可調用對象,這個可調用對象在__getitem__碰到找不到的鍵時,讓__getitem__返回一個默認值。
key = "name" dict_demo2 = collections.defaultdict(list) print(dict_demo2) dict_demo2[key].append((1,2)) print(dict_demo2) dict_demo2["pass"] print(dict_demo2)
運行結果:
defaultdict(<class 'list'>, {}) defaultdict(<class 'list'>, {'name': [(1, 2)]}) defaultdict(<class 'list'>, {'name': [(1, 2)], 'pass': []})
dict_demo2一開始是一個空字典,不存在任何鍵值,當運行dict_demo2[key]時,其中包含一下三個步驟:
(1) 調用list()建立一個新列表
(2) 把這個新列表做爲值,key做爲鍵,放入dd中
(3) 返回這個列表的引用(這也是可以進行append操做的緣由)
若是在鍵值不肯定的狀況下能夠考慮使用defaultdict
全部映射類型在處理找不到的鍵時,都會牽扯__missing__方法,當__getitem__操做找不到鍵值時,就會調用__missing__方法,而不是直接拋出異常。
__missing__方法只會被__getitem__方法調用
class StrKeyDict0(dict):
def __missing__(self, key): if isinstance(key, str): raise KeyError(key) return self[str(key)] def get(self, key, default=None): try: return self[key] except KeyError: return default def __contains__(self, key): return key in self.keys() or str(key) in self.keys()
if name == '__main__':
d = StrKeyDict0([('2', 'two'), ('4', 'four')]) print(d['2']) print(d[4]) try: print(d[1]) except KeyError: print("keyerror") print(d.get('2')) print(d.get(4)) try: print(d.get(1, 'N/A')) except KeyError: print("keyerror") print(2 in d) print(4 in d)
運行結果:
two four keyerror two four N/A True True
__missing__方法中將鍵key轉化爲str類型後再次嘗試獲取字典d中相應的鍵值
因此能夠看到,即使字典中沒有 4 這個鍵,可是依然可以正確獲取其在字典中相應的值,可是因爲字典中不存在 1 或 "1" 這樣的鍵,因此沒法獲取d[1]