Python基础知识 2022-11-14 ★ 小结 43-50 字典_集合

字典

字典的特点

无序、可变、键值对
每个元素是一个键值对,包含键对象和值对象
键对象不可以重复(字典是一个依靠键对象的散列值来排列元素的散列表,键对象的散列值不可以重复)

创建方式

a = {'name':'marx','age':18,'salary':'unknown'}
a = dict('name'='marx','age'=18),键值对的元组
a = dict[('name','marx'),('age',18)],键值对元组组成的列表
a = dict(zip(键列表,值列表)),zip()方式也同样适用于元组
a = dict.formkeys(['name','age']),创建值对象为空的字典,注意其中键对象是以列表形式出现,而不是只用逗号隔开

字典元素的访问

a['name'],类似列表和元组中用a[0]的访问方式
a.keys(),列出字典a中所有的键对象
a.items(),列出字典a中所有的键值对
a.values(),列出字典a中所有的值对象
a.get('name'),获取字典a中’name’键对象的值对象
len(a),获取字典a的键值对个数
'name' in anot in,判断键对象是否在字典a中

字典元素的添加

a['address'] = '南天门',如果字典a中没有address这个键,就添加这个键值对;如果有,就更新值对象
a.update(b),b是一个新的字典,将b字典中的内容拷贝到字典a中,重复键就覆盖,没有的键就新增

字典元素的删除

del(a['name']),删除字典a中键对象为name的键值对
a.clear(),清空字典a,字典a变成空字典
a.pop('name'),返回值是name的值对象,抛出name后字典a中就没有这个键值对了
a.popitem('name'),乱序抛出字典a中的键值对,当a为空字典时会抛异常

字典的序列解包

序列解包用于列表

[a,b,c]=[10,20,30]
❓ 去掉方括号好像没有影响

序列解包用于元组

x,y,z = (10,20,30)
(x,y,z) = (10,20,30)
❓ 不太理解列表和元组的序列解包的区别,看起来都是一次性对三个变量赋值

序列解包用于字典

序列解包用于字典默认是对键对象进行操作

a = {'name':'gaoqi','age':18,'job':'programmer'}
m,n,l = a

序列解包对字典中的值对象进行操作
e,f,g = a.values()
序列解包对字典中的键值对进行操作
e,f,g = a.items()

表格的构建和打印,列表和字典综合嵌套

思路:

  1. 构造表格
    1. 字典构建每一行,需要储存数据
    2. 列表装起来每一行,需要按重复格式增殖
  2. 打印
    1. 循环的是行数,也就是列表的元素数
    2. 按字典键对象打印值对象
r1 = {"name":"高小一", "age":18, "salary":30000, "city":"北京"}
r2 = {"name":"高小二", "age":19, "salary":20000, "city":"上海"}
r3 = {"name":"高小五", "age":20, "salary":10000, "city":"深圳"}

tb = [r1,r2,r3]

#获得第二行的人的薪资
print(tb[1].get('salary'))

#打印所有人的薪资
for i in range(len(tb)):
    print(tb[i].get('salary'))
#打印所有数据
for i in range(len(tb)):
    print(tb[i].get('name'),tb[i].get('salary'),tb[i].get('city'))

字典核心底层原理

字典的本质是一个散列表,即稀疏数组,即总是有空白元素的数组
散列表中的每个单元叫bucket(表元、桶)
每个bucket有两个部分:键对象的引用、值对象的引用
所有bucket的结构、大小都一样,通过偏移量来读取指定的bucket
字典的键对象:必须可散列,即可以转换出哈希值,字符串、数字、元组皆可

把键对象放入字典的底层过程
  1. 计算键对象的散列值bin(hash('name')
    1. 数组长度假设为8,也就是最小的索引值是7,是最大的3位二进制数,
  2. 取name的散列值最右端的3位,转换为0-7的索引值,假设为6
  3. 索引值为6的bucket是否为空
    1. 为空,将name键对象放入该bucket
    2. 不为空,取name散列值从最右端往左移动3位后的3位数,转换为0-7的索引值…重复步骤2,直到找到空bucket
根据键查找键值对的底层过程

跟上面这个差不多

  1. 算出键对象的散列值x
  2. 从散列值最右取值,转换成序号,找bucket的索引值
  3. 看bucket是否为空
    1. 为空,返回None
    2. 不为空,
      1. 取出该bucket中的键对象,算出该键对象的散列值y
      2. 对比x与y是否相等
        1. 相等,返回该bucket对应的值对象
        2. 不相等,回到步骤2,往左移动3位再找bucket
字典底层原理小结
  • 键对象必须是可以散列的
    • 数字、字符串、元组
    • 自定义对象满足以下条件
      • 支持hash()函数
      • 支持通过__eq__()方法检验相等性
      • 若 a==b为真,则hash(a)==hash(b)也为真
  • 键查询很快
  • 字典是以空间换时间
  • 字典中添加新建可能会导致扩容,导致散列表中键的次序改变,因此不要在遍历字典的同时对字典进行修改

集合

集合的特点

集合的底层就是字典,但只有字典的键对象
集合是无序的、可变的、元素不能重复的(跟字典几乎一样)

集合的创建

a = {'a','b','age'}
a = set(b),将可迭代对象b转换为集合,如果有重复元素就会只留下一个

集合的删除

a.clear(),清空后得到一个空集合a
a.remove(10),删除集合a中的指定元素10

集合的其它操作

就像数学中的集合,并集、交集、差集
并集:a|b, a.union(b)
差集:a-b, a.difference(b)
交集:a&b, a.intersecion(b)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值