dict类型可以说是python里模块的命名空间,实例的属性,函数的关键字参数都有其的参与。
set的实现也依赖于散列表
常见的字典方法:
如之前所述:
Container:
__contains__
Iterable:
__iter__
Sized:
__len__
Mapping:
__getitem__
__contains__
__eq__
__ne__
get
items
keys
values
MutableMapping
__Setitem__
__defitem__
clear
pop
popitem
setdefault
update
只有可散列的数据类型才能做mapping的键,根据文档里的说法:
The keys can be any object with __hash__() and __eq__() methods.
只有实现了__hash__()和__eq__()方法的才能作为键
不可变的序列都可视为可散列的,但是
hash((1,2,3))
Out[1]: 2528502973977326415
hash((1,2,[2,3]))
Traceback (most recent call last):
File "<ipython-input-2-2a1f9780b624>", line 1, in <module>
hash((1,2,[2,3]))
TypeError: unhashable type: 'list'
里面包含了可变序列,也是不可hash的
字典推导:
a = [1,2,3,4,5]
b = {index:element for index,element in enumerate(a)}
b
Out[5]: {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
如何处理查找不到的键:
用setdefault处理找不到的键,可以避免tey/except方法
正常来说,一个字典里面没有的键:
b
Out[5]: {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
b[5]
Traceback (most recent call last):
File "<ipython-input-6-ca5d543a082a>", line 1, in <module>
b[5]
KeyError: 5
会报错的,但是实现了setdefault方法呢?
b.setdefault(5,'default')
Out[7]: 'default'
b[5]
Out[8]: 'default'
这样的话,只需要检测b[5]是不是指定的值了。
当然还有更简单的,collections模块里的defaultdict或者自己定义一个dict的子类,在子类中实现__missing__方法
1.
d = collections.defaultdict(str)
d[2]
Out[21]: ''
在这里的输入值必须是可调用对象,比如str,list,set,int,string是不行的。
d = collections.defaultdict(23)
Traceback (most recent call last):
File "<ipython-input-15-cc8c566b0851>", line 1, in <module>
d = collections.defaultdict(23)
TypeError: first argument must be callable or None
2.
class NewDict(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 isinstance(key, str):
raise KeyError(key)
就会出现如下错误:
RecursionError: maximum recursion depth exceeded while calling a Python object
因为self[str(key)]会调用__getitem__,但是str(key)又不存在,于是就会报错
class NewDict(dict):
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return 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()
a = NewDict()
a[2]
Out[40]: '2'
这样变相的实现了我们需要的值
标准库中字典的变种:
collections里的
OrderedDict:在添加键的时候会保持顺序,popitem是默认删除最
ChainMap:可容纳数个不同的映射对象,在进行键查找时会被作为一个整体查找
Counter:会给键准备一个计数器,用于计数键的更新次数
UesrDict:用纯python实现的dict,常用来方便用户继承
不可变映射类型,实际上可以理解为视图
MappingProxyType
集合:本质是许多唯一对象的聚集
交集&,并集|这些基本集合操作都有