一个健映射多个值
from collfaultdict import defaultdict
#自动为访问的健创建一个列表实体
d = defaultdict(list)
d[‘key’].append(1)
d[‘key’].append(2) # d[‘key’] -> [1, 2]
# 集合实体
s = defaultdict(set)
s[‘key’].add(3)
s[‘key’].add(4) # s[‘key’] -> {3, 4}
python3.5之前字典
- 定义空字典
d = {}
会初始化一个8*3二维数组entries = [[_, _, _],[_, _, _]…]
存储数据 - 添加数据时
d[key] = value
,计算key的hash值并对8取余数h = hash(key)%8
,不同session会有不同的hash随机种子,python的hash函数的结果每次重新打开python时可能会改变 - 将数据存储在
entries
下标为h
的位置entries [h][0] = hash(key), entries[h][1] = key_address, entries [h][2] = value_address
二维数组三个值为key的hash值, key字符串所在内存地址, value所在内存地址 - 遍历字典就是在遍历这个二维数据
- 第二次添加数据的
h
可能比第一次小,所以字典顺序与添加数据顺序不一致 - 当两个key的
h
相同时,通过开放寻址技术寻找新位置,解决散列冲突 - 当健值对的数量大于数组长度的2/3时数组将会扩容8行变16行,16行变32行,扩容会导致
h
发生变化,需要移动数据,减低插入效率
python3.6之后字典
- 定义空字典
d = {}
会初始化indices = [None*8]
和entries = []
- 添加数据时
d[key] = value
,计算h
,把indices下标为h
的位置修改为0 - entries.append([hash(key), key_address, value_address])
- 再次添加数据,把indices下标为
h
的位置修改为1,entries再append一条数据 - 取数据时,先计算
h
,通过p = indices[h]
获取数据位置,再通过v = entries[p]
拿到数据 - 由于每次添加数据都是往entries后面添加数据,所有遍历数据的顺序与插入顺序一致
- 遍历的次数与entries长度一样,大部份情况小于老字典(8*n)
- 内存占用在大部份的情况下也小于老字典,假如现在有3条数据3*3*8+8=80 byte (3行,3元素,每个元素8字节,一维数组占8字节)而老字典为8*3*8=192 byte(8行,3个元素,每个元素占8字节)
字典极值
min(zip(d.values(), d.keys()))
max(zip(d.values(), d.keys()))
min(d, key=lambda x:d[x])
max(d, key=lambda x:d[x])
- zip创建的是生成器,只能访问一次
- 元组的最大小值在第一个元素相等时,通过比较第二个元素大小
字典比较
通过集合操作
a.values()
不能进行集合操作,因为会存在重复的值
a.keys() & b.keys()
a.items() - b.items()
a.items() | b.items()
a.keys() ^ b.keys()
字典过滤
c={key:a[key] for key in a.keys - {“a”, “b”}}
本文含有隐藏内容,请 开通VIP 后查看