字典(dict)和集合(set)是无序的
字典推导
values = [1, 2, 3]
dict1 = {key: value for key, value in enumerate(values)}
print(dict1)
输出结果
{0: 1, 1: 2, 2: 3}
集合推导式
set1 = {i **2 for i in range(3)}
print(set1)
输出结果为
{0, 1, 4}
特殊方法 __missing__
所有映射映射类型在找不到的键的时候,都会牵扯到__missing__方法,__missing__方法只会被__getitem__方法调用, 提供__missing__方法对get或者__contains__方法这些方法的使用没有影响。
字典的变种
collections.OrderedDict
这个类型在添加键的时候会保持顺序,因此键的迭代次序总是一致的。
collections.Counter
这个映射类型会给键准备一个整数的计数器,每次更新一个键的时候都会增加这个计数器
collections.UserDict
这个类其实是把标准的dict用纯python又实现了一遍
dict和set的背后
- python里的dict和set的效率为什么高?
- 为什么他们都是无序的?
- 为什么并不是多有的python对象都可以当作dict的键和set的值?
- 为什么dict 的键和set元素的顺序是根据他们被添加的次序而定的,以为为什么映射对象的生命周期中,这个顺序并不是一成不变的?
- 为什么不应该在迭代循环dict和set的同时往里面添加元素?
dict的实现及其导致的后果
1 键必须是可散列的
(1)支持hash()函数,并通过__hash__()函数得到的散列值是不变的
(2)支持并通过__eq__方法来检测相等性
(3)若a == b 为真,那么hash(a) = hash(b) 也为真
2 字典在内存上的开销巨大
由于字典是散列表,而散列表又必须是稀疏的,这导致他在空间上的效率很低下
3 键查询快
4 键的次序取决于添加顺序
5 往字典中添加新键可能会改变已有键的顺序
无论何时往字典中添加新键,Python解释器都可能做出为字典扩容的决定,扩容导致结果就是要新建一个更大的散列表,并把字典里已有的元素添加到新表里,这个过程中可能会发生散列冲入,导致新散列表中的键的次序变化。
set的实现以及导致的结果
- 集合里的元素必须是可散列的
- 集合很消耗内存
- 可以很高效的判断元素是否存在于某个集合
- 元素的次序取决于被添加到集合里的次序
- 往集合里添加元素,可能会改变集合里已有元素的次序