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]