第七讲目录
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210130103605651.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3OTQwMDQ4,size_16,color_FFFFFF,t_70)
1.数据结构简介
- 数据结构(Data Structures)基本上人如其名——它们只是一种结构,能够将一些数据聚合 在一起。换句话说,它们是用来存储一系列相关数据的集合。
- Python中有四种内置的数据结构——列表(List)、元组(Tuple)、字典(Dictionary)和集合(Set)
- 列表在上一章博客。本章博客中将介绍元组(Tuple)、字典(Dictionary)。
2.元组tuple
2.1元组简介
元组用于将多个对象保存到一起,近似看作列表,但是元组不能提供列表类广泛的功能,元组类似于字符串,不可变,不能修改元组。指定项目时,给他们加上括号,并在括号内部使用逗号进行分隔。
- 元组表现形式tuple
- 元组是一个不可变序列(一般当我们希望数据不改变时,我们使用元组,其他情况下基本都用列表)
- 使用()创建元素
- 元组不是空元组至少有一个 逗号(,) 当元组不是空元组时括号可以省略
- 元组解包指将元组当中的每一个元素都赋值给一个变量
2.2元组的表达形式及创建
- 元组内的数据是不可变话的,不可更改的, 在不希望数据发生改变的时候我们就用元组,其余的情况都用列表
# 元组的表达形式 () tuple
tuple1 = (1, 2, 3, 4, 5)
print(tuple1, type(tuple1))
# 运行结果 》》》(1, 2, 3, 4, 5) <class 'tuple'>
print(tuple1[2])
# 运行结果 》》》3
print(tuple1[2::])
# 运行结果 》》》(3, 4, 5)
# 如果元组不是一个空元祖,那么它必须得有一个逗号
tuple2 = 6,
tuple3 = (6)
print(tuple2, type(tuple2))
# 运行结果 》》》(6,) <class 'tuple'>
print(tuple3, type(tuple3))
# 运行结果 》》》6 <class 'int'>
2.3拆包
-
拆包的时候如果有*, 那么有且只能有一个*, *接受参数之后,结果是用一个列表来放置的。
-
元组的拆包
tuple4 = (1, 2, 3, 4)
*a, b, c = tuple4
print(a, b, c)
# 运行结果 》》》[1, 2] 3 4
a, *b, c = tuple4
print(a, b, c)
# 运行结果 》》》1 [2, 3] 4
a, b, *c = tuple4
print(a, b, c)
# 运行结果 》》》1 2 [3, 4]
- 字符串的拆包
a = 'abcde'
b, *c= a
print(b, c)
# 运行结果 》》》a ['b', 'c', 'd', 'e']
*b, c= a
print(b, c)
# 运行结果 》》》['a', 'b', 'c', 'd'] e
- 列表的拆包
list1 = [1, 2, 3, 4, 5]
a, *b = list1
print(a, b)
# 运行结果 》》》1 [2, 3, 4, 5]
*a, b = list1
print(a, b)
# 运行结果 》》》[1, 2, 3, 4] 5
3.字典dict
3.1字典简介
字典:mapping 映射关系 key:value 一个字典中, 每一个key都是唯一的,我们只需要通过key就可以查找到我们需要的数据, key-value我们称之为键值对,也可以称呼它为一项item
将键值(Keys)与值(Values)联系到一起,键值必须是唯一的,成对的键值和值之间用冒号分割,每一对键值对使用逗号区分,全部由一对花括号括起。字典中的键值对不会以人为方式进行排序,只能在使用它们之前自行进行排序
3.2字典创建
- 空字典的创建
dict1 = {}
print(dict1, type(dict1))
# 运行结果 》》》{} <class 'dict'>
- 字典赋值创建
* dict2 = {
'姓名': 'Seasons in the sun',
'年龄': 26,
'性别': '男',
'爱好': '编程'
}
print(dict2, type(dict2))
# 运行结果 》》》{'姓名': 'Seasons in the sun', '年龄': 26, '性别': '男', '爱好': '编程'} <class 'dict'>
# 当字典中的key有重复的时候,后面的key-value会替换前面的
dict2 = {
'姓名': 'Seasons in the sun',
'年龄': 26,
'性别': '男',
'爱好': '编程',
'爱好': '乒乓球'
}
print(dict2, type(dict2))
# 运行结果 》》》{'姓名': 'Seasons in the sun', '年龄': 26, '性别': '男','爱好': '乒乓球'} <class 'dict'>
- 使用dict类去创建字典
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
print(dict1, type(dict1))
# 运行结果 》》》{'姓名': 'Seasons in the sun', '年龄': 26, '性别': '男'} <class 'dict'>
- dict双值子序列创建字典
dict2 = dict([('姓名', 'Seasons in the sun'), ('年龄', 26), ('性别', '男')])
print(dict2, type(dict2))
# 运行结果 》》》{'姓名': 'Seasons in the sun', '年龄': 26, '性别': '男'} <class 'dict'>
这里我们介绍一下什么是双值子序列, 首先我们看一下双值序列 ,
如列表[1, 2]就是双值序列,
再看一下什么是子序列,字符串’a’就可以作为一个子序列,
之后再看一下我们这里的双值子序列[(1, 2), (3, 4)]
简单一点来说呢,这个就是序列之间的嵌套,例如上面的列表与元组嵌套
3.字典的修改(增删改查)
3.3.1 len()
# len()
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
print(len(dict1))
# 运行结果 》》》3
3.3.2 in 与 not in
# in not in 检测的是key
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
print('姓名' in dict1)
# 运行结果 》》》True
print(26 in dict1)
# 运行结果 》》》False
3.3.3 获取值
# 使用key获取value dict[key] 如果不存在key则会报错
# dict.get(key) 不存在key不会报错
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
print(dict1.get('爱好'))
# 运行结果 》》》None
# print(dict1.dict['爱好']) 这样用就会报错
3.3.4 修改字典
# dict[key] = value
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
dict1['姓名'] = '郭靖'
print(dict1)
# 运行结果 》》》{'姓名': '郭靖', '年龄': 26, '性别': '男'}
3.3.5 dict.setdefault添加key-value
# 如果这个key已经存在于字典中,则返回value,不会对字典有影响,
# 如果不存在,则向字典中添加这个key,并设置value
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
result = dict1.setdefault('姓名', '郭靖')
print(result)
print(dict1)
# 运行结果 》》》
Seasons in the sun
{'姓名': 'Seasons in the sun', '年龄': 26, '性别': '男'}
result = dict1.setdefault('爱好', '编程')
print(result)
print(dict1)
# 运行结果 》》》
python
{'姓名': 'Seasons in the sun', '年龄': 26, '性别': '男', '爱好': '编程'}
3.3.6 dict.update()
# dict.update() 将其他字典中的key—value添加到当前字典中
d1 = {'男': 1}
d2 = {'女': 2}
d1.update(d2)
print(d1)
# 运行结果 》》》{'男': 1, '女': 2}
3.3.7 del 关键字删除
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
del dict1['姓名']
print(dict1)
# 运行结果 》》》{'年龄': 26, '性别': '男'}
3.3.8 dict.popitem()随机删除
# dict.popitem() 随机删除一个键值对,一般都会删除最后一个, 有一个返回值,就是你删除的对象,结果是一个元组
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
result = dict1.popitem()
print(result)
print(dict1)
# 运行结果 》》》
('性别', '男')
{'姓名': 'Seasons in the sun', '年龄': 26}
3.3.9 dict.pop 删除
# dict.pop(key,[default]) 根据key来删除键值对, 返回值就是你删除key对应的value
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
result = dict1.pop('性别')
print(result)
print(dict1)
# 运行结果 》》》
男
{'姓名': 'Seasons in the sun', '年龄': 26}
result = dict1.pop('爱好', '你删除的这个不存在')
print(result)
print(dict1)
# 运行结果 》》》
你删除的这个不存在
{'姓名': 'Seasons in the sun', '年龄': 26}
3.3.10 清空字典
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
# dict.clear() 清空字典
dict1.clear()
print(dict1)
# 运行结果 》》》{}
3.4 字典的遍历
遍历这个概念在上一章的for循环中也提到过,当时是说列表可以当成遍历来使用,咱们这里的字典也同样可以哦,接下来我们讲讲字典如何遍历。
- 遍历的规则如下:
for i(迭代变量) in 序列(遍历的规则):
循环体
- 通过key来遍历 dict.keys()
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
for k in dict1.keys():
print(dict1[k])
# 运行结果 》》》
Seasons in the sun
26
男
- 通过value来遍历 dict.values()
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
for v in dict1.values():
print(v)
# 运行结果 》》》
Seasons in the sun
26
男
- 通过一项来进行遍历 dict.items()
dict1 = dict(姓名='Seasons in the sun',年龄=26,性别='男')
for k, v in dict1.items():
print(k, '=', v)
# 运行结果 》》》
姓名 = Seasons in the sun
年龄 = 26
性别 = 男
4.深拷贝和浅拷贝
4.1、什么是深拷贝和浅拷贝?
- 都先作为做拷贝的对象必须是可变类型,如列表,字典
- 深拷贝
深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
深拷贝是在引用方面不同,深拷贝就是创建一个新的和原始字段的内容相同的字段,是两个一样大的数据段,所以两者的引用是不同的,之后的新对象中的引用型字段发生改变,不会引起原始对象中的字段发生改变。
- 浅拷贝
浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。
浅拷贝是将原始对象中的数据型字段拷贝到新对象中去,将引用型字段的“引用”复制到新对象中去,不把“引用的对象”复制进去,所以原始对象和新对象引用同一对象,新对象中的引用型字段发生变化会导致原始对象中的对应字段也发生变化。
- 总结
深拷贝主要是将另一个对象完全复制一遍,开辟自己的内容区域,即使更改也与原本的对象没有如何关系。
浅拷贝主要拷贝的是对象的引用值,就是把他的地址拿过来,自然而然随着值的更改,原对象的值也会更改。
4.2 实际操作
- 浅拷贝
import copy
dict1 = {'1': 1, '2': 2}
dict2 = {'1': 1, '2': 2}
print(id(dict1), id(dict2))
# 运行结果 》》》1588506094688 1588506094760
dict1 = {'1': 1, '2': 2, 'list1': [1, 2, 3, {'name': [12, 23]}]}
dict2 = copy.copy(dict1)
print(id(dict1), id(dict2))
# 运行结果 》》》1588507018296 1588506094688
dict2 = dict1.copy()
print(id(dict1['list1']), id(dict2['list1']))
# 运行结果 》》》1588508504648 1588508504648
浅拷贝只能对第一层的数据进行拷贝,如果,第一层的数据也是个可变类型,那么浅拷贝无法将这个数据重新拷贝一份形成新的id
- 深拷贝
import copy
dict1 = {'1': 1, '2': 2, 'list1': [1, 2, 3, {'name': [12, 23]}]}
dict3 = copy.deepcopy(dict1)
print(id(dict1), id(dict3))
# 运行结果 》》》1588508590368 1588508590944
print(id(dict1['list1']), id(dict3['list1']))
# 运行结果 》》》1588508505736 1588508505672
深拷贝则可以对所有的数据全部进行拷贝,形成一个新的id
5.课后作业
第一题
a = {"name":"123","data":{"result":[{"src":"python1"},{"src":"python2"},{"src":"python3"}]}}
b = a["data"]["result"]
print(b[0]["src"],b[1]["src"],b[2]["src"])
运行结果如下:
- 知识点运用及编写思路:
本题中的a字典有4层嵌套,字典套字典套列表套字典,先取出内层的列表存储在b中,再分别取出对应的值即可,需注意的是,取字典的值是通过对应的key取得,取列表的值是通过索引取得。
第二题
a = [11,22,33,44,55,66,77,88,99,90]
greater_lst = []
less_lst = []
for i in a:
if i > 66:
greater_lst.append(i)
elif i < 66:
less_lst.append(i)
else:
continue
dict1 = {'key1': greater_lst,'key2':less_lst}
print(dict1)
运行结果如下:
- 知识点运用及编写思路:
使用用for循环遍历列表a,判断列表中所有的数,大于66的就用append方法添加到列表greater_lst,小于66的就添加到列表 less_lst,等于66的就跳过。最后将greater_lst和less_lst赋值给dict1,输出即可。