工程师们大家好,配套免费视频(平时上班周末录制)
文章目录
之前学习了列表,知道列表是可以增删改查的,在开发中,我们经常是一个地方去添加好我们需要的数据比如list1 然后需要把这个list1传给别的地方使用, 注意了:昨天说到列表的复制的时候(可以回顾一下),也就是我们把list1给别人是给的地址值,如果别人对这个list1改变了,那么所有使用list1的地方都会改变。例如:
list1 = ['a','b','c']
给list1 给一个地方 比如A
在把list1 给另外一个地方 比如B
那么这三个地方都是用的同一个地址,也就是如果A这个地方改变了这个list1 那么B也跟着改变。
那么我们不希望他的改变相互影响呢?可以使用昨天copy,还有其他办法吗?
有 就是可以使用一种不变的列表:就是元组(tuple)
1.元组(tuple)
⼀个元组可以存储多个数据(可以是不同数据类型哦),元组内的数据是不能修改的
列表是用[] 元组用小括号,其他索引什么的都是类似的,不过元组不能增删改
1.1创建元组
直接创建元组
t1 = (1, 2, 3, '中国')
print(t1) # (1, 2, 3, '中国')
t2 = 4, 5, 6, '中国'
print(t2) # (4, 5, 6, '中国')
t3 = (1,) # 注意这里有一个逗号哦
print(t3) # (1,)
t3 = (1) # 不写逗号是int类型
print(t3) # 1
print(type(t3)) # <class 'int'>
t4 = 1,
print(t4) # (1,)
range循环创建
r5 = range(5) # 生成0 1 2 3 4的range
# i for i in r5 # 循环r5里面的数据 挨个赋值给i
t5 = tuple(i for i in r5) # 挨个赋值给i了后 全部收集 形成一个元组
print(t5) # (0, 1, 2, 3, 4)
# 也可以简写
tuple5 = tuple(r5) # 直接把r5强转为一个元组
print(tuple5)
zip创建嵌套元组
t1 = (1, 2, 3, 4)
t2 = ('A', 'B', 'C', 'D')
t1_t2 = zip(t1, t2)
print(t1_t2) # <zip object at 0x0000016DF5EB2D08>
t1_t2_tuple = tuple(t1_t2)
print(t1_t2_tuple) # ((1, 'A'), (2, 'B'), (3, 'C'), (4, 'D')) 元组里面套元组
# 如果 t1 t2 的个数不一致 以少的为准(木桶定理)
1.2元组切片
跟list完全相同,简单举例一个了
t = (1, 2, 3, 4)
t1 = t[:3] # 0-3 不包含3
print(t1) # (1, 2, 3) 并没有改变原来的元组t 是新建了一个元组
1.3元组常用方法
t = (1, 2, 3, 4)
print(len(t)) # len方法获得元组的个数长度 结果:4
print(t.index(1)) # 获得1这个元素在元组t里面的下标 结果:0
print(t.count(2)) # 获得2这个元素在元组t里面出现的次数 结果:1
print(t[1]) # 返回元组t 下标为1的元素 结果:2
# TypeError: 'tuple' object does not support item assignment
t[1] = 5 # 直接报错 元组的元素不能修改
1.4元组遍历
t = (1, 2, 3, 4)
for item in t:
print(item)
# 当然也可以利用下标遍历 挺简单自己做下
2.字典(dict)
比如我们要记录一个学生的成绩
语文--100
数学--149
英语--60
这个应该有两组列表:第一组:['语文','数学','英语'] 第二组:[100,149,60]
可不可以一组呢?
第一种方案:['语文---100','数学---149','英语---60']
可以是可以 但是万一我要改下数学成绩呢?挺麻烦呀,先拿到字符串在改字符串
第二种方案:只要一个[100,149,60] 然后规定下标0是语文,下标1数学 2 英语。。。。99代表化学
也可以,但是如果成绩科目很多,但是人家只有英语成绩,你也得创建这样大一个数组(因为下标是固定的呀) 内存浪费
其次也不直观,得记住所有的下标,成绩太多不太现实
类似于这种,前后两组数据,并且是一一对应的关系,就可以用字典来存储。
{'语文':100,'数学':149,'英语':60}
这样是不是很直观了?注意格式哦,大括号 然后一组数据之间是冒号,不同组数据之间是逗号
然后每组数组比如:'语文':100 我们把语文称为 key 100称为value
2.1创建字典
# 第一种:方式通过 大括号直接创建
student = {'name': '张三', 'age': 10, 'address': '成都'}
print(student)
print(type(student)) # <class 'dict'> 字典类型
# 第二种:也可以通过dict构造方法 来创建 大家还不会 先放在这有个印象
# 注意 这个不是元组
d = dict(name="张三", age=18, pay=40000, job="Python工程师")
print(d)
print(type(d))
# 第三种:keys---values 一对一关系
keys = ['name', 'age', 'address']
values = ['张三', 10, '成都']
dict1 = dict(zip(keys, values)) # 先采用zip压缩 再强转为字典
print(dict1)
print(type(dict1))
# 第四种
keys = ['name', 'age', 'address']
# 调用dict的方法创建
# 以keys的每一个元素为key 后面的哈哈哈为value
fromkeys = dict.fromkeys(keys, '哈哈哈')
# 结果:{'name': '哈哈哈', 'age': '哈哈哈', 'address': '哈哈哈'}
print(fromkeys)
# tips:大家先记得第一种
2.2增加元素
student = {} # 定义一个空的字典
# 前面指定 key 后面是value
student['name'] = '张三'
student['age'] = 10
print(student) # {'name': '张三', 'age': 10}
2.3删除元素
del
student = {'name': '张三', 'age': 10}
del student['name'] # 根据name这个key删除一组元素
print(student) # {'age': 10}
del student # 直接删除student
print(student) # NameError: name 'student' is not defined
pop
student = {'name': '张三', 'age': 10}
pop = student.pop('name') # 删除指定key那一对
print(pop) # 张三 返回被删除key的value
print(student) # {'age': 10}
popitem
student = {'age': 10, 'name': '张三'}
popitem = student.popitem() # 删除后面一对键值对 比如这里就是删除name
print(popitem) # ('name', '张三') 这里是元祖
print(student) # {'age': 10}
# 删除完了 再删除要报错
clear
student = {'age': 10, 'name': '张三'}
student.clear() # 清空
print(student) # {}
2.4修改
student = {'age': 10, 'name': '张三'}
student['name'] = '李四' # 把原来name对应的value改成李四
print(student)
student.update({'name': '王五'}) # 在把name改成王五
print(student)
2.5单个查询
student = {'age': 10, 'name': '张三'}
name_ = student['name'] # 根据name键获得值
print(name_)
get = student.get('age') # 根据get键获得值
print(get)
student_get = student.get('a') # 不存在这个键的时候返回None
print(student_get) # 结果:None
student_get = student.get('a', 'abc') # 根据a取值 如果不存在这个key 就返回后面的默认值abc
print(student_get) # 结果:abc
a_ = student['a'] # 不存在的时候直接跑异常 KeyError: 'a'
2.6遍历
keys:
student = {'age': 10, 'name': '张三'}
keys = student.keys() # 获得所有key组成一个dict_keys类型,可以先不纠结类型
print(keys) # dict_keys(['age', 'name'])
print(type(keys)) # <class 'dict_keys'>
# 上面一般不单独用 都是遍历使用
for key in keys:
print(key, "-----", student[key])
values:
student = {'age': 10, 'name': '张三'}
values = student.values() # 返回所有的value 类型是dict_values,可以先不纠结类型
print(values) # <class 'dict_values'>
print(type(values)) # <class 'dict_values'>
for value in values:
print(value)
items:
student = {'age': 10, 'name': '张三'}
items = student.items()
print(items) # dict_items([('age', 10), ('name', '张三')])
print(type(items)) # <class 'dict_items'>
# 类型先不用纠结 key看到每组数据都形成了一个元组
# 可以遍历元组
'''
('age', 10)
('name', '张三')
'''
for item in items:
print(item)
# 也可以这样遍历
'''
age ---- 10
name ---- 张三
'''
for key, value in items:
print(key, '----', value)
也可以最简单的:
student = {'age': 10, 'name': '张三'}
for key in student:
print(key, '----', student[key])
2.7复制
student = {'age': 10, 'name': '张三'}
student1 = student
print(id(student1))
print(id(student))
copy = student.copy()
print(id(copy))
# 打印结果:
'''
1773603227040
1773603227040
1773603227112
可以看到 直接等号 是把地址值给了student1 那么修改student1 也会影响到student
第二种是生成了一个新的地址值 互不影响 切记切记
'''
3.集合
用大括号构成:
set1 = {'张三', '李四', '王五', 4, 1, 5, 1} # 定义一个集合
print(set1)
'''
打印结果:# {1, 4, 5, '李四', '张三', '王五'}
可以看出:1.集合是不允许用重复的元素自动去除
2.无序的(其实跟dict的key类似 使用hash算法)
3.必须是不可变类型
'''
# set1 = {'张三', '李四', '王五', 4, 1, 5, 1,{}}
# 这样创建会报错 TypeError: unhashable type: 'dict' 意思字典是可变类型
# 比如字典 列表都是可变类型 这里的可变不可变,是指内存中的那块内容(value)是否可以被改变
# 也可以这样创建
set2 = set('abcde123') # 将abcde123字符串的每个元素组成集合
print(set2) # {'c', '1', 'a', 'b', '2', 'd', '3', 'e'}
3.1增加
set1 = {1, 2}
set1.add(3) # 集合加一个元素3
print(set1) # {1, 2, 3}
set1.update('456') # 把456字符串拆分后加入集合
print(set1) # {'5', 1, 2, 3, '4', '6'}
set2 = {8, 9}
set1.update(set2) # 相当于是并集
print(set1) # {1, 2, 3, 8, 9, '6', '5', '4'}
3.2修改
修改就没有啦,因为也没有下标 也没有key update方法我认为是增加更恰当
3.3删除
set1 = {1, 2, 3, 4, 5, 6, '张三'}
pop = set1.pop() # pop() 方法用于随机移除一个元素 应该跟hash算法有关 后面看源码来讨论
print(pop) # 返回被删除的元素
print(set1)
# 删除集合中2这个元素
remove = set1.remove(2) # 不返回删除的元素
print(remove)
print(set1) # {3, 4, 5, 6, '张三'}
# 删除集合中3这个元素
discard = set1.discard(3)
print(discard) # None
print(set1) # {4, 5, 6, '张三'}
set1.clear() # 清空
print(set1) # set()
set2 = {1, 2}
set2.discard(3) # 弹出没有的元素 discard不报错
set2.remove(3) # 弹出没有的元素 报错 KeyError: 3
# 没有元素 pop()报错 # TypeError: pop expected at least 1 arguments, got 0意思至少一个元素
3.4遍历
iter:
set1 = {1, 2, 3, 4, 5, 6, '张三'}
i = iter(set1)
for value in i:
print(value, end='\t')
print()
for value in set1:
print(value, end='\t')
# 可以遍历
3.5交集
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
set_ = set1 & set2 # 返回set1与set2的交集
print(set_) # {3, 4}
intersection = set1.intersection(set2) # 同上
print(intersection)
# 求set1 与set2的交集
# 区别是:上面交集是形成一个新的集合set1未改变 而这个是把set1改变了
update = set1.intersection_update(set2)
print(update) # None
print(set1) # {3,4}
isdisjoint = set1.isdisjoint(set2)
print(isdisjoint) # false 如果两个集合有交集就返回false 否则True
3.6并集
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
set_ = set1 | set2 # set1 与set2的并集
print(set_) # {1, 2, 3, 4, 5, 6}
union = set1.union(set2) # 同上
print(union)
# 也是求set1与set2的并集
# 上面是形成一个新的集合 set1 set2都没变
# 下面是改变了set1
update = set1.update(set2)
print(update)
print(set1) # {1, 2, 3, 4, 5, 6}
3.7差集
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
set_ = set1 - set2 # set1 与set2的差集{1,2} 反过来就是56
print(set_)
difference = set1.difference(set2) # 同上
print(difference)
# 都是差集 不过上面的方法是形成一个新的集合
# 下面是改变了set1本身
update = set1.difference_update(set2)
print(update) # None
print(set1) # {1,2}
3.8子父集
set1 = {1, 2, 3, 4}
set2 = {3, 4} # set2的全部元素都在set1中 set2是set1的子集
set_ = set1 > set2
print(set_) # True 判断set2是否是set1的子集
issubset = set2.issubset(set1)
print(issubset) # true 判断set2是否是set1的子集
issuperset = set1.issuperset(set2)
print(issuperset) # true判断set1是否是set2的父级
3.9对称差
对称差的意思:两个集合差集的集合
1 2 3 -----2 3 4 得到的结果是1 4
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
difference = set1.symmetric_difference(set2)
print(difference) # {1, 2, 5, 6}
set_ = set1 ^ set2
print(set_) # 同上
# 都是对称差 但是上面是把对称差放在一个新的集合
# 下面是直接在set1里面更改了
update = set1.symmetric_difference_update(set2)
print(update)
print(set1)