德州网站建设赖殿波,厦门蓝典网站建设,网站权重,个人入驻的跨境平台系列文章目录
Python序列之列表Python序列之元组Python序列之字典#xff08;本篇文章#xff09;Python序列之集合 Python序列之字典 系列文章目录前言一、字典是什么#xff1f;二、字典的操作1.创建#xff08;1#xff09;通过{}、dict()创建#xff08;2#xff0…系列文章目录
Python序列之列表Python序列之元组Python序列之字典本篇文章Python序列之集合 Python序列之字典 系列文章目录前言一、字典是什么二、字典的操作1.创建1通过{}、dict()创建2通过zip()创建3通过fromkeys()创建值为空的字典 2.元素的访问1通过[键]获得“值”。2通过get()方法获得“值”。3列出所有的键值对、所有的键、所有的值4用len()计算键值对的个数5用in检测一个键是否在字典中 3.元素的添加、修改、删除1给字典新增键值对。2使用update()将新字典中所有键值对全部添加到旧字典对象上。3删除元素del()、clear()与pop()4popitem()随机删除和返回该键值对。 4.序列解包5.练习用字典对表格数据进行存取 三、字典的底层原理重要1存储键值对的过程2查找值对象的过程 总结 前言
前面我们已经讲了Python中的列表Python序列之列表和元组Python序列之元组 。今天我们再来看一下Python中另一种常用的序列——字典。
一、字典是什么
字典是 “键值对”的无序可变序列。字典中的每个元素都是一个“键值对”包含“键对象和值对象”即key:value对可以通过“键对象实现快速获取、删除、更新对应的值对象。 一个典型的字典的定义方式
a {name: yyy, age: 3, job: programmer}列表中我们通过”下标数字找到对应的对象字典中通过“键对象“找到对应的“值对象”。
“键”是任意的不可变数据比如整数、浮点数、字符串、元组。但是列表、字典、集合这些可变对象不能作为“键”。并且“键”不可重复。“值”可以是任意的数据并且可重复。
二、字典的操作
1.创建
1通过{}、dict()创建
a {name: yyy, age: 3, job: programmer}
b dict(nameyyy, age3, jobprogrammer)
c dict([(name, yyy), (age, 3), (job, programmer)])
d {} # 创建一个空字典
e dict() # 创建一个空字典print(a) # 输出{name: yyy, age: 3, job: programmer}
print(b) # 输出{name: yyy, age: 3, job: programmer}
print(c) # 输出{name: yyy, age: 3, job: programmer}
print(d) # 输出{}
print(e) # 输出{}2通过zip()创建
既然可以用上面创建c的方式创建字典那自然可以用zip()函数
keys [name, age, job]
values [yyy, 3, programmer]
d dict(zip(keys, values))
print(d) # 输出{name: yyy, age: 3, job: programmer}3通过fromkeys()创建值为空的字典
k [name, age, job]
d dict.fromkeys(k)
print(d) # 输出{name: None, age: None, job: None}小问题之前说字典的“键”不可重复如何重复了会怎样会报错吗
a {name:yyy, age:18, age:3}
print(a) # 输出{name: yyy, age: 3}可见如果键重复了后面的键值对会把前面的覆盖掉。
2.元素的访问
1通过[键]获得“值”。
若键不存在则抛出异常。
a {name: yyy, age: 3, job: programmer}
print(a[name]) # 输出yyy
print(a[height]) # 输出报错KeyError: height2通过get()方法获得“值”。
**推荐使用**优点是指定键不存在返回None也可以设定指定键不存在时默认返回的对象。推荐使用get()获取值对象”。
a {name: yyy, age: 3, job: programmer}
print(a.get(name)) # 输出yyy# 使用get()不会报错整个过程变得很优雅~
print(a.get(height)) # 输出None# 还尅通过第二个参数指定当键不存在时的返回值
print(a.get(height, 185)) # 输出1853列出所有的键值对、所有的键、所有的值
a {name: yyy, age: 3, job: programmer}b a.items()
print(b) # 输出ict_items([(name, yyy), (age, 3), (job, programmer)])k a.keys()
print(k) # 输出dict_keys([name, age, job])v a.values()
print(v) # 输出dict_values([yyy, 3, programmer])4用len()计算键值对的个数
a {name: yyy, age: 3, job: programmer}
print(len(a)) # 输出35用in检测一个键是否在字典中
a {name: yyy, age: 3, job: programmer}
print(name in a) # 输出True
print(height in a) # 输出False3.元素的添加、修改、删除
1给字典新增键值对。
如果键已经存在则覆盖旧的键值对如果键不存在则新增键值对。
a {name: yyy, age: 18, job: programmer}
a[height] 185
a[age] 3
print(a) # 输出{name: yyy, age: 3, job: programmer, height: 185}2使用update()将新字典中所有键值对全部添加到旧字典对象上。
如果key有重复则直接覆盖
a {name: yyy, age: 3, job: programmer}
b {name: sheep, height: 185, gender: man}
a.update(b)
print(a) # 输出{name: sheep, age: 3, job: programmer, height: 185, gender: man}3删除元素del()、clear()与pop()
字典中元素的删除可以使用del()方法或者者clear()删除所有键值对pop()删除指定键值对并返回对应的“值对象”。
a {name: yyy, age: 3, job: programmer, height: 185}del(a[name])
print(a) # 输出{age: 3, job: programmer, height: 185}age a.pop(age)
print(a) # 输出{job: programmer, height: 185}
print(age) # 输出3a.clear()
print(a) # 输出{}4popitem()随机删除和返回该键值对。
字典是无序可变序列因此没有第一个元素、最后一个元素的概念popitem()弹出随机的项因为字典并没有最后的元素或者其他有关顺序的概念。若想一个接一个地移除并处理项这个方法就非常有效因为不用首先获取键的列表)
a {name: yyy, age: 3, job: programmer, height: 185}result1 a.popitem()
result2 a.popitem()print(result1) # 输出(height, 185)
print(result2) # 输出(job, programmer)
print(a) # 输出{name: yyy, age: 3}4.序列解包
序列解包可以用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值。
x, y, z (20, 30, 10)
(a, b, c) (9, 8, 10)
[m, n, p] [a, b, c]序列解包用于字典时默认是对键进行操作如果需要对键值对操作则需要使用items()如果需要对值进行操作则需要使用values();
a {name: yyy, age: 3, job: programmer}
x, y, z a
print(x) # 输出namex, y, z a.items()
print(x) # 输出(name, yyy)x, y, z a.values()
print(x) # 输出yyy5.练习用字典对表格数据进行存取
数据表格如下
姓名年龄薪资城市张三1810000北京李四1930000上海王五2020000深圳
people1 {name: 张三, age: 18, salary: 10000, city: 北京}
people2 {name: 李四, age: 19, salary: 30000, city: 上海}
people3 {name: 王五, age: 20, salary: 20000, city: 深圳}
# 存进一张表格
table [people1, people2, people3]
# 访问表格数据
for i in range(len(table)):print(table[i].get(name), table[i].get(age), table[i].get(salary), table[i].get(city))# 输出
# 张三 18 10000 北京
# 李四 19 30000 上海
# 王五 20 20000 深圳三、字典的底层原理重要
1存储键值对的过程
字典对象的核心是散列表。散列表是一个稀疏数组总是有空白元素的数组数组的每个单元叫做bucket。每个bucket有两部分一个是键对象的引用一个是值对象的引用。由于所有bucket结构和大小一致我们可以通过偏移量来读取指定bucket。 先创建一个字典a
a {}a[name] yyy假设字典a对象创建完后数组长度为8 我们要把’name’yyy’这个键值对放到字典对象a中首先第一步需要计算键name的散列值。Python中可以通过hash()函数来计算。
print(bin(hash(name))) # 输出-0b1010111101001110110101100100101由于数组长度为8我调拿计算出的散列值的最右边3位数字作为偏移量即101十进制是数字5。我们查看偏移量5对应的bucket是否为空。如果为空则将键值对放进去。如果不为空则依次取右边3位作为偏移量即100十进制是数字4。再查看偏移为4的bucket是否为空。直到找到为空的bucket将键值对放进去。流程图如下:
那如果当前数组满了怎么办很简单——扩容。 python会根据散列表的拥挤程度扩容。“扩容指的是创造更大的数组将原有内容拷贝到新数组中。接近2/3时数组就会扩容。
2查找值对象的过程
明白了一个键值对是如何存储到数组中的根据键对象取到值对象理解起来就简单了。 a.get(name)
yyy当调用a.get(name)就是根据键’name’查找到键值对从而找到值对象’yyy’。我们仍然要首先计算’yyy’对象的散列值 bin(hash(name))
-0b1010111101001110110101100100101和存储的底层流程算法一致也是依次取散列值的不同位置的数字。假设数组长度为8我们可以拿计算出的散列值的最右边3位数字作为偏移量即101十进制是数字5。我们查看偏移量5对应的 bucket是否为空。如果为空则返回 None。如果不为空则将这个bucket的键对象计算对应散列值和我们的散列值进行比较如果相等。则将对应值对象返回。如果不相等则再依次取其他几位数字重新计算偏移量。依次取完后仍然没有找到。则返回 None。流程图如下 总结
字典在内存中开销巨大典型的用空间换时间。键查询速度很快。往字典里面添加新建可能导致扩容导致散列表中键的次序变化。因此不要在遍历字典的同时进行字典的修改键必须可散列 数字、字符串、元组都是可散列的自定义对象需要支持下面三点面向对象章节中再展开说 ①支持hash()函数 ②支持通过_eq_()方法检测相等性 ③ 若ab为真则 hash(a)hash(b)也为真