python cookbook笔记2-字典

发布于:2023-01-16 ⋅ 阅读:(456) ⋅ 点赞:(0)

一个健映射多个值

 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之前字典

  1. 定义空字典d = {}会初始化一个8*3二维数组entries = [[_, _, _],[_, _, _]…]存储数据
  2. 添加数据时d[key] = value,计算key的hash值并对8取余数h = hash(key)%8,不同session会有不同的hash随机种子,python的hash函数的结果每次重新打开python时可能会改变
  3. 将数据存储在entries下标为h的位置entries [h][0] = hash(key), entries[h][1] = key_address, entries [h][2] = value_address二维数组三个值为key的hash值, key字符串所在内存地址, value所在内存地址
  4. 遍历字典就是在遍历这个二维数据
  5. 第二次添加数据的h可能比第一次小,所以字典顺序与添加数据顺序不一致
  6. 当两个key的h相同时,通过开放寻址技术寻找新位置,解决散列冲突
  7. 当健值对的数量大于数组长度的2/3时数组将会扩容8行变16行,16行变32行,扩容会导致h发生变化,需要移动数据,减低插入效率

python3.6之后字典

  1. 定义空字典d = {} 会初始化indices = [None*8]entries = []
  2. 添加数据时d[key] = value,计算h,把indices下标为h的位置修改为0
  3. entries.append([hash(key), key_address, value_address])
  4. 再次添加数据,把indices下标为h的位置修改为1,entries再append一条数据
  5. 取数据时,先计算h,通过p = indices[h]获取数据位置,再通过v = entries[p]拿到数据
  6. 由于每次添加数据都是往entries后面添加数据,所有遍历数据的顺序与插入顺序一致
  7. 遍历的次数与entries长度一样,大部份情况小于老字典(8*n)
  8. 内存占用在大部份的情况下也小于老字典,假如现在有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])
  1. zip创建的是生成器,只能访问一次
  2. 元组的最大小值在第一个元素相等时,通过比较第二个元素大小

字典比较

通过集合操作
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 后查看