字典
字典的key
必须是可散列的数据类型,实现了__hash__()
和__qe__()
方法。
字典推导
字典推导可以从任何以键值对作为元素的可迭代对象中构建出字典。
1 | dial = [('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')] |
setdefault
类似于collections.defaultdict
,在查询不到key
时不会抛出异常而是返回默认值。
1 | dial = [('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'), ('key4', 'value4')] |
__missing__
所有的映射类型在处理找不到的键时,都会牵扯到__missing__
方法。基类dict
虽然没有提供该方法,但是如果一个类继承了dict
,并且提供__missing__
方法,那么在__getitem__
找不到键时便会自动调用__missing__
方法。
1 | class mydict(dict): |
另外__missing__
方法只会被__getitem__
调用,不会被get
或者__contains__
调用。
collections.OrderDict
添加键的时候会保持顺序,因此键的迭代次序可以保持一致。popitem()
方法默认删除最后一个添加的键值对,提供参数last=False
时删除第一个。
collections.ChainMap
1 | from collections import ChainMap |
collections.UserDict
用纯Python的方式把标准的dict
实现了一遍,提供给用户继承写子类。但collections.UserDict
并不是dict
的子类。
不可变映射类型
MappingProxyType
可以返回一个只读的映射试图,并且是动态的。我们可以通过这个代理访问到源映射但是无法作出修改,从而保证了数据的安全性。
1 | from types import MappingProxyType |
字典的特点
- 内存开销大,散列表是稀疏数组导致了大内存的开销。
- 键查询速度快。
- 往字典里添加新建可能会导致已有键的顺序改变。—-那么如何避免这个问题呢?
集合论
集合中的元素必须是可散列的,set
类型本身是不可散列的。集合的本质是许多唯一对象的集合,因此集合可以用于去重。接受一个可迭代对象去掉重复部分。
1 | set([1,2,3,4,5,6,6,5,4,3,2,1]) |
中缀运算符:
|
合集&
交集-
差集^
对称差in
属于<=
包含于<
真包含于
集合推导
1 | l = [1,2,3,4,5,6,6,5,4,3,2,1] |
集合的其他方法
s.add(e)
添加s.clear()
清空s.copy()
浅复制s.discard(e)
移除,不存在不抛出异常s.remove(e)
异常,不存在抛出异常s.pop()
随机移除,不存在抛出异常
集合的特点
- 元素必须是可散列的。
- 内存开销大,由上一条特点导致。
- 可以高效的判断元素是否存在某一个集合中。
- 元素次序取决于添加次序
- 添加新元素可能破坏原有次序。
散列表
- 散列表是一个稀疏数组(总是有空白的数组称为稀疏数组)。散列值在理想情况下越是相似,他们的散列值差别越大。
- 盐值:盐值是python进程中的一个常量,每次启动Python解释器生成的盐值都不相同。盐值主要用于计算对象的散列值。在计算散列值时随机加盐可以防止DOS攻击。
- 散列表的算法:略
- 可散列的条件:
- 支持
hash()
函数,并且通过__hash__()
方法得到的散列值是不变的(同一次启动解释器中不变,加盐的原因不同次不相等) - 支持通过
__eq__()
方法来检测相等性。 - 如
a == b
则hash(a) == hash(b)
- 支持