第三章 字典与集合
1、如果一个对象是可散列的,在它的声明周期中,它的散列值是不变的;
原子不可变数据类型(str、bytes和数值类型)都是可散列类型,frozenset也是可散列的,元祖的话,只有当一个元祖包含的所有元素都是可散列类型的情况下,它才是可散列的。
2、re.compile(r'\w+')
re.compile()方法用于字符串匹配
在字符串前面加个r 就是表示字符串等于其书写的原始格式,不进行转义
\w 表示匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”
3、enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
4、defaultdict默认在找不到键的情况下新建一个对象,如
index = collections.defaultdict(list)
在找不到k的情况下index[k]会调用default_factory创造某个默认值,而dd.get(k)则会返回None,此处其实是特殊方法__missing__在起作用
5、__missing__方法只在__getitem__中调用,如index[k],而对get和__contains__方法没有影响
6、字典推导:可以从任何以键值对作为元素的可迭代对象中构建出字典
7、字典的变种
collections.OrderedDict 添加键的时候保持顺序,因此迭代次序总是一致的,可以作先进先出或者先进后出 |
collections.ChainMap 可以容纳多个不同的映射对象,在查找键时,会逐个查找,直到找到为止 |
collections.Counter 用于计数 |
UserDict 让用户继承写子类 |
8、继承的写法:class StrKeyDict(collections.UserDict):
9、不可变的字典类型:标准库中没有,但是可以用替身来代替
from types import MappingProxyType
d = {1: 'A'}
d_proxy = MappingProxyType(d)
print(d_proxy)
print(d_proxy[1])
# d_proxy[2] = 'x'
d[2] = 'B'
print(d_proxy)
print(d_proxy[2])
print(d)
10、集合的元素必须是散列的,采用集合可以加速很多的& | intersection 等可以加速计算,创建空集合时必须采用set(),若用{}创建出来的是空字典
11、集合操作
s & z | s.__add__(z) |
|
z & s | s.__rand__(z) |
|
s.intersection(it,…) |
| |
s &= z | s.__iadd__(z) |
|
s.intersection_update(it,…) |
| |
s | z | s.__or__(z) |
|
z | s | s.__ror__(z) |
|
s.union(it,…) |
| |
s |= z | s.__ior__(z) |
|
s.update(it,…) |
| |
s - z | s.__sub__(z) |
|
z – s | s.__rsub__(z) |
|
s.difference(it,…) |
| |
s -= z | s.__isub__(z) |
|
s.difference_update(it,…) |
| |
s.symmetric_difference(it) | 求s和set(it)的对称差集 | |
s ^ z | s.__xor__(z) |
|
z ^ s | s.__rxor__(z) |
|
s.symmetric_difference_update(it,…) | 把可迭代的it和其他参数转化为集合,求它们与s的对称差集,最后把s更新成该结果 | |
s ^= z | s.__ixor__(z) | 把s更新成它与z的对称差集 |
12、对称差集:A与B中所有不属于A与B交集的元素
13、集合的比较运算符
| s.isdisjoint(z) | 是否不相交 |
e in s | s.__contains__(e) |
|
s <= z | s.__le__(z) | 是否是子集 |
s.issubset(it) | 把it转化为set,判断是否为子集 | |
s < z | s.__lt__(z) | s是否为真子集 |
s >= z | s.__ge__(z) | 是否为父集 |
s.issuperset(it) |
| |
s > z | s.__gt__(z) | 是否为真父集 |
14、散列表是一个稀疏数组(总有空白元素的数组称为稀疏数组)
15、dict字典的特性
1)键必须是可散列的,支持__hash__和__eq__,且 == 成立时,hash值也必须一致
2)内存上存在巨大开销:由于散列表是稀疏的
3)键查询很快,1000万个元素的字典,一秒可以完成200万个键查询
4)键的次序取决于添加顺序,但是顺序不同,元素相同时,hash也是一致的
5)往字典里添加新键,可能会改变已有键的顺序,因此对字典不能同时进行迭代与修改
16、set、frozenset的特性,与字典相似
1)元素必须可散列
2)集合很消耗内存
3)可以很高效地判断元素是否存在于某集合中
4)元素的次序取决于被添加到集合里的次序
5)往集合添加元素,可能会改变集合里已有元素的次序