- 📢博客主页:盾山狂热粉的博客_CSDN博客-C、C++语言,机器视觉领域博主
- 📢努力努力再努力嗷~~~✨
💡大纲
👉列表:列表的创建、列表性质(长度、索引、切片)、操作列表(列表元素的增删查改、列表的复制、列表的排序翻转、遍历列表)
👉元组:元组性质(不可变列表)、操作元组(不支持任何关于元组本身的修改)、常见用法(打包、解包)
👉字典:字典的创建、字典性质(索引)、操作字典(键值对的增删改、遍历字典)
👉集合:集合的表达形式、集合运算、操作集合(元素的增删、遍历集合)
一、列表(有序,可修改)
❓什么是列表???
👉序列类型:内部元素有位置关系,可通过位置序号访问
👉可以存放多种类型的数据
(一)列表的创建
1、创建空白对象
list1 = list() # 通过循环给空列表赋值
2、直接赋值
ls = ["Python", C, 1234, {"Day": 10.16}]
ls
# ['Python', C, 1234, {'Day': 10.16}]
3、list(可迭代对象)
💡可迭代对象:字符串、元组、集合、range()等
👉字符串转列表、元组转列表、集合转列表、range()转列表
list("今天是周末") # ['今', '天', '是', '周', '末']
list(("你", "我", "他", "她")) # ['你', '我', '他', '她']
list({"盾山", "东皇", "鲁大", "小鲁班"}) # ['盾山', '东皇', '小鲁班', '鲁大']
list(range(1, 11, 2)) # [1, 3, 5, 7, 9]
❓认识一下range()
for i in [0, 1, 2, 3, 4, 5]: print(i) for i in range(6): print(i) # 两者的结果是一样的
👉range(起始数字,中止数字,数字间隔)
👉起始数字缺省,默认为0;数字间隔缺省,默认为1
⚠️中止数字不能省略,读取的时候不包含中止数字
for i in range(1, 11, 2): print(i, end=" ") # 1 3 5 7 9
(二)列表的性质
1、列表的长度---len(列表)
2、列表的索引---与同为序列类型的字符串完全相同
H = ["盾山", "东皇", "鲁班", "鲁大"]
print(H[0]) # 盾山
print(H[-1]) # 鲁大
3、列表的切片(正向、反向)---同字符串
👉变量名[开始位置:结束位置:切片间隔]
👉正向:开始位置小于结束位置,切片间隔为正数
👉反向:开始位置大于结束位置,切片间隔为负数
(三)列表的操作符
1、列表的拼接---list1+lis2(类似与字符串的拼接,用的不多)
2、列表的成倍复制---n*list(可作为初始化 列表的一种方式)
[0]*10 # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 重复列表内的元素若干次
(四)列表的操作
1、增加元素
💡在列表末尾增加元素---列表.append(待增元素)
H = ["盾山", "东皇", "鲁班"]
H.append("鲁大")
# H[len(H):] = ["鲁大"] 通过切片的方式添加
H # ['盾山', '东皇', '鲁班', '鲁大']
💡在列表任意位置插入元素---列表.insert(位置编号,待增元素)
H = ["盾山", "东皇", "鲁班"]
H.insert(1, "鲁大")
H # ['盾山', '鲁大', '东皇', '鲁班']
💡在列表1的末尾加上整个列表2---列表1.append(列表2)
💡将列表2内的元素逐个添加到列表1中---列表1.extend(列表2) 可以使用切片的方式添加
list1=["C","C++","R"]
list2=["Python","Java"]
list1.append(list2)
list1.extend(list2)
# 对比list1
# ['C', 'C++', 'R', ['Python', 'Java']]
# ['C', 'C++', 'R', 'Python', 'Java']
2、删除元素
💡删除列表任意位置的元素---列表.pop(位置编号)或del 列表[位置编号]
👉对于列表.pop(位置),会返回删除的元素;不写位置信息时,默认删除最后一个元素
list1 = ['Python', 'C', 'C++', 'R', 'Java']
list1.pop(2)
print(list1)
del list1[2]
print(list1)
'''
['Python', 'C', 'R', 'Java']
['Python', 'C', 'Java']
'''
💡删除列表中的第一次出现的待删元素---列表.remove(待删元素)
list1 = ['Python', 'C', 'R', 'C', 'Java']
list1.remove("C")
list1 # ['Python', 'R', 'C', 'Java']
# 删除字符串中某个指定的元素
list1 = ['Python', 'C', 'R', 'C', 'Java']
while "C" in list1:
list1.remove("C")
list1 # ['Python', 'R', 'Java']
💡清空列表---列表.clear()
3、查找元素
💡返回列表某个元素出现的次数---列表.count(待查元素)
💡返回列表中第一次出现待查元素的位置---列表.index(待查元素)
list1 = ['Python', 'C', 'R','Java']
idx = list1.index("R")
# idx = list1.index("R", 1, 3) # 查找元素,查找的范围
idx # 2
4、修改元素
💡通过"先索引后赋值"的方式,对元素进行修改---列表名[位置]=新值
5、列表的复制
👉如果以list1给list2赋值,那么两者共用一段数据,在list1中修改,两者的输出都会被修改。这里是对列表的引用
👉以浅拷贝的方式进行列表的复制
💡克隆---列表.copy()
list1 = ['Python', 'C', 'R','Java']
list2 = list1.copy()
list1.pop()
print(list1) # ['Python', 'C', 'R']
print(list2) # ['Python', 'C', 'R', 'Java']
💡切片---列表[:]
list1 = ['Python', 'C', 'R','Java']
list2 = list1[:]
list1.pop()
print(list1) # ['Python', 'C', 'R']
print(list2) # ['Python', 'C', 'R', 'Java']
⚠️浅拷贝在二维列表中会有错误,x改后,y也会对应的改
👉浅拷贝只拷贝了外层的对象,如果包含嵌套对象时,拷贝的只是其引用,需要用到深拷贝
⭕深拷贝需要导入copy模块,有两个函数copy()、deepcopy()
👉深拷贝在进行拷贝时会把拷贝对象所有的内容进行拷贝
6、列表的排序
💡对列表进行永久排序(默认升序)---列表.sort()
👉只能处理列表
👉直接在列表上进行操作
list1 = [2, 5, 2, 8, 19, 3, 7]
list1.sort()
list1 # [2, 2, 3, 5, 7, 8, 19]
👉如果想要改为降序
list1.sort(reverse = True)
list1 # [19, 8, 7, 5, 3, 2, 2]
💡列表进行临时排序---sorted(列表)
👉原列表保持不变,返回排序后的列表
list1 = [2, 5, 2, 8, 19, 3, 7]
list2 = sorted(list1)
print(list1) # [2, 5, 2, 8, 19, 3, 7]
print(list2) # [2, 2, 3, 5, 7, 8, 19]
👉改为降序
sorted(list1, reverse = True)
# [19, 8, 7, 5, 3, 2, 2]
7、列表的翻转
💡对列表进行永久翻转---列表.reverse()
👉直接在列表上进行操作,无返回值
list = [1, 2, 3, 4, 5]
print(list[::-1]) # [5, 4, 3, 2, 1],这是以切片的方式翻转
list # [1, 2, 3, 4, 5]
list.reverse()
list # [5, 4, 3, 2, 1]
8、列表的遍历
list = [1, 2, 3, 4, 5]
for i in list:
print(i,end=" ")
# 1 2 3 4 5
9、列表的嵌套
A = [0] * 3 # [0, 0 ,0]
for i in range(3):
A[i] = [0] * 3 # 创建3*3的二维列表 [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
S = [[0] * 3 for i in range(3)] # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
💡创建二维列表的方法,A才是真正意义上的创建了二维列表
(五)列表推导式
'''[表达式 for 变量 in 列表 (if 条件)]'''
# 列表生成元素表达式,可以是有返回值的函数
# 迭代列表,将变量传入到表达式
# 条件语句,可以过滤列表中不符合条件的值,只有满足条件的才可以使用
1、案例
📑过滤字符串长度小于或等于3的字符串,并将剩下的转换为大写字母
names = ["Bob","Tom","Jerry","Smith"]
new_name = [name.upper() for name in names if len(name)>3]
print(new_name) # ['JERRY', 'SMITH']
📑计算30以内可以被3整除的数字
num = [i for i in range(30) if i % 3 == 0]
print(num,end=" ") # [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
2、嵌套的列表推导式
二、元组(不可修改)
❓什么是元组???
👉序列类型:内部元素有位置关系,可通过位置序号访问
👉可以存放多种类型的数据
⚠️与列表相比:元组一旦定义,内部元素不允许修改操作,其他操作与列表一样
⚠️元组可看作不可变的列表
(一)元组
👉元素中只包含一个元素时,需要在元素后面添加逗号,表示这是元组
tup1 = (50) # 这是当作整数的
print(type(tup1))
tup2 = (50,) # 加上逗号,表示这是元组
print(type(tup2))
'''
<class 'int'>
<class 'tuple'>
'''
(二)元组的常见用法
1、打包
x,y = 10,20 # 其实是_ = (10,20)进行打包,然后再解包
def f1(x): # 返回x的平方和立方
return x**2, x**3 # 实现打包返回
print(f1(3)) # (9,27)
print(type(f1(3))) # 元组类型<class 'tuple'>
2、解包(列表、元组、字符串)
a, b = f1(3) # 实现解包赋值
print(a) # 9
print(b) # 27
3、元组的嵌套
4、元组推导式?
👉有列表推导式,但是不存在元组推导式的,会得到一个生成器
(三)关于元组的元素是不可变的
💡元组中存放的是元素的地址,不可变指的是元组所指向的内存中的内容不可变,如果元组里的元素指向一个可变的列表,依然可以修改列表里的值
👉重新赋值后的元组tup1,其实是重新创建的,因为地址改变了
tup1=(1,2,3)
print(id(tup1)) # tup1的内存地址
tup1=(4,5,6,7)
print(id(tup1)) # 重新赋值后tup1的内存地址
'''
2744756391752
2744752371336
'''
(四)实例
numbers = [201901, 201902, 201903]
name = ["小明", "小红", "小强"]
list(zip(numbers,name)) # [(201901, '小明'), (201902, '小红'), (201903, '小强')]
for number,name in zip(numbers,name): # 每次取到一个元组,立刻进行解包赋值
print(number, name)
# 201901 小明
# 201902 小红
# 201903 小强
三、字典(有序,可修改) 在python3.7以后
❓什么是字典???
👉字典的键是不能重复的,如果重复了,随机读取重复键的一个键值
👉字典的键必须是不可变类型,不能更改键值,因为键与键值一一对应
👉不可变类型:数字、字符串、元组
👉可变类型:列表、字典、集合
(一)创建字典:7种方法
a = {"吕布":"口口布","关羽":"关习习","刘备":"刘baby"}
b = dict(吕布="口口布",关羽="关习习",刘备="刘baby") # 要求键不能加引号
c = dict([("吕布","口口布"),("关羽","关习习"),("刘备","刘baby")]) # 将列表传入dict函数,列表内容为映射关系的元组
d = dict( {"吕布":"口口布","关羽":"关习习","刘备":"刘baby"}) # 不用,跟第一种一样
e = dict( {"吕布":"口口布","关羽":"关习习"},刘备="刘baby") # 混合方法
f = dict(zip(["吕布","关羽","刘备"],["口口布","关习习","刘baby"])) # zip函数将两个列表组合成一个二元组
g = dict.fromkeys(可迭代对象,数值(none))
(二)字典的性质
1、字典的长度---键值对的个数
len(d)
2、键是否在字典中:键 in 字典
'C' in d # True
3、字典转换为列表
💡字典中的所有键构成一个列表
list(d) # ['F', 'i', 's', 'h', 'C']
list(d.keys())
list(d.values()) # ['70', 105, 115, 104, '67']
4、将字典设置为一个迭代器
💡创建一个字典迭代器---iter(字典)
e = iter(d)
next(e) # 依次读取迭代器内容
5、逆序字典的键、键值
💡将字典的键、键值顺序颠倒---reversed(d.values())
list(reversed(d.values())) # ['67', 104, 115, 105, '70']
list(reversed(d)) # ['C', 'h', 's', 'i', 'F']
(三)字典的相关操作
1、增加键值对
💡形式:fromkeys(iterable[, values])
👉将iterable参数指定的可迭代对象来创建一个字典,并将所有的键值初始化为values参数指定的值
👉键名是可迭代对象的每个元素,键值是values参数(默认情况下是none)
👉需要修改键值时,就通过正常的访问来修改
d = dict.fromkeys("fish",250) # {'f': 250, 'i': 250, 's': 250, 'h': 250}
d['f'] = 70 # {'f': 70, 'i': 250, 's': 250, 'h': 250}
💡变量名[新键] = 新值
👉如果创建的新键名已存在,那么新键值覆盖旧键值
d['c'] = 80 # {'f': 70, 'i': 250, 's': 250, 'h': 250, 'c': 80}
2、删除键值对
💡删除任意键
👉del 字典名[待删除键]
👉del 字典名,删除整个字典
d = {'f': 70, 'i': 250, 's': 250, 'h': 250, 'c': 80}
del d['f'] # {'i': 250, 's': 250, 'h': 250, 'c': 80}
del d # 删除整个字典,不能再进行访问,会抛出异常
💡变量名.pop(待删除键),会返回键值
👉删除不存在的键会抛出异常,可以设置默认值来规避异常。以下列形式:字典.pop(不存在的键,自己写的内容)
d.pop('s') # 250 返回键值
d.pop('狗') # 抛出异常
d.pop('狗',"没有该键") # '没有该键'
💡删除末尾键值对---字典名.popitem(),需要两个变量来接收返回的删除键值对
d = {'f': 70, 'i': 250, 's': 250, 'h': 250, 'c': 80}
key, value = d.popitem()
print(key,value) # c 80
print(d) # {'f': 70, 'i': 250, 's': 250, 'h': 250}
💡清空字典---字典名.clear()
d = dict.fromkeys("fishc",250)
d.clear() # {}
3、修改键值
💡通过先索引后赋值的方式对相应的值进行修改
👉可以通过update函数来更新多个键值对,传入的参数可以是另一个字典,也可以是包含映射关系的可迭代对象
d = dict.fromkeys("FishC")
d['s'] = 115 # {'F': None, 'i': None, 's': 115, 'h': None, 'C': None
d.update({'i':105,'h':104})
d.update(F='70',C='67') # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}
4、获取键值
💡获取字典中某一键值对的值
👉从字典d中获取键key对应的值,如果没有这个键,则返回default---d.get(key,default)
d.get('C') # 67
d.get('c','这里没有c') # '这里没有c'
💡在获取字典中某一个键值对的键值时,若该键存在,则输出键值;若键不存在,则将查找的键与默认键值组成键值对添加进字典---d.setdefault(键,默认键值)
d.setdefault('C','code') # 67
d.setdefault('c','code') # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67', 'c': 'code'}
📑统计字符串中字符出现的频率
love = "亲亲我吧爱我吧"
d = {}
print(d)
for i in love:
d[i] = d.get(i, 0)+1 # 创建键值对
print(d)
'''
{}
{'亲': 1}
{'亲': 2}
{'亲': 2, '我': 1}
{'亲': 2, '我': 1, '吧': 1}
{'亲': 2, '我': 1, '吧': 1, '爱': 1}
{'亲': 2, '我': 2, '吧': 1, '爱': 1}
{'亲': 2, '我': 2, '吧': 2, '爱': 1}
'''
💡获取整个字典的键值对、键与值的视图对象---d.items()、d.keys( )、d.values( )
👉视图对象的内容是动态、可修改的
keys = d.keys() # dict_keys(['F', 'i', 's', 'h', 'C', 'c'])
values = d.values() # dict_values(['70', 105, 115, 104, '67', 'code'])
items = d.items() # dict_items([('F', '70'), ('i', 105), ('s', 115), ('h', 104), ('C', '67'), ('c', 'code')])
d.pop('c') # 'code'
d # {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}
keys # dict_keys(['F', 'i', 's', 'h', 'C'])
5、字典的遍历
for k, v in Hero.items():
print(k, v)
'''
101 盾山
102 东皇
103 鲁大
'''
6、字典的嵌套
💡将字典的键值改为另一个嵌套的字典,访问时是两次索引
d = {"吕布":{"语文":60,"数学":60,"英语":90},"关羽":{"语文":50,"数学":60,"英语":40},"刘备":{"语文":70,"数学":30,"英语":80}}
d["刘备"]["英语"] # 80
(四)字典推导式
d = {'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}
b = {v:k for k,v in d.items()} # {'70': 'F', 105: 'i', 115: 's', 104: 'h', '67': 'C'}
# 利用字典推导式求出字符串的编码值
d = {x:ord(x) for x in "FishC"} # {'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
# 对于两个循环,在第一次循环后,第二次循环对于键值进行覆盖了
d = {x:y for x in [1,3,5] for y in [2,4,6]}
d # {1: 6, 3: 6, 5: 6}
四、集合(无序,可变)
❓什么是集合???
👉是一系列互不相等元素的集合,可用于去重
👉元素必须是不可变类型
⚠️与字典的关系:集合的元素可以看作字典的键,集合可以看作没有值或值为None的字典。在后续的学习中知道,字典的键与集合的元素都是可哈希的
s = [1,1,2,3,4,5]
# 判断有没有重复元素
len(s) == len(set(s)) # False
(一)集合的运算
两个班级的授课老师S、T
S = {"王老师", "吴老师", "郭老师", "刘老师", "赵老师", "张老师"}
T = {"王老师", "张老师", "吴老师", "陈老师", "赵老师", "林老师"}
1、交集
💡S.intersection(T)
👉S & T 返回一个新集合,包括同时在集合S和T中的元素
👉可以多参数
S & T # {'吴老师', '张老师', '王老师', '赵老师'}
S.intersection(T)
2、并集
💡S.union(T)
👉返回一个新集合,包括集合S和T中的所有元素
👉可以多参数
S | T # {'刘老师', '吴老师', '张老师', '林老师', '王老师', '赵老师', '郭老师', '陈老师'}
S.union(T)
3、非共同元素集合(对称差集)
💡s.symmetric_difference(可迭代对象)
👉S ^ T 返回一个新集合,包括集合S和T中的非共同元素(交集的补集)
👉不可以多参数
S ^ T # {'刘老师', '林老师', '郭老师', '陈老师'}
s = set("FishC")
s.symmetric_difference("Python") # {'C', 'F', 'P', 'i', 'n', 'o', 's', 't', 'y'}
4、in S not in T
💡S.difference(T)
👉S - T 返回一个新集合,包括在集合S但不在集合T中的元素
👉可以多参数
S - T # {'刘老师', '郭老师'}
T - S # {'林老师', '陈老师'}
S.difference(T)
5、检测子集或超集
💡集合.issubset(可迭代对象) 集合.issuperset(可迭代对象)
s.issubset("I Love python.com") # True
s.issuperset("py") # Ture
s = set("FishC")
s <= set("FishC") # True 子集
s < set("FishC") # False 真子集
s >= set("Fish") # True
s > set("FishC") # False 真超集
⭕在用符号进行计算时需要注意,操作数只能是集合;使用操作符进行计算时 ,可以使用所有可迭代对象
👉所有计算都是返回新的集合,并不是修改原本的集合
(二)集合的创建:3种方法
1、集合推导式
💡集合数据是无序的
{s for s in "FishC"} # {'C', 'F', 'h', 'i', 's'}
2、set()函数
👉创建空集合必须用函数set(),集合名 = set(可迭代对象)
👉集合名 = {value1, value2,……}
set("FishC") # {'C', 'F', 'h', 'i', 's'}
3、直接创建
(三)set()与frozenset()
💡两者都是集合,差别在于可变与不可变,不可变指的是内容不能修改
👉set是可变的集合
👉frozenset是不可变的集合
t = frozenset("FishC") # frozenset({'C', 'F', 'h', 'i', 's'})
1、前面说的所有方法两者都可以使用
2、仅适用于set()的方法
- 增加集合元素
💡使用函数参数others指定的值来更新集合,插入新的元素---s.update(*others)
👉others表示支持多参数,other只支持一个参数
👉因为集合中不能有重复的元素,所以[1,1]只会更新一个1,然后"23"在集合中随机更新
👉需要注意的是每一个参数的内容都是通过迭代的方式添加进集合的,并不是整体
s = set("FishC")
s.update([1,1],"23") # {1, '2', '3', 'C', 'F', 'h', 'i', 's'}
💡将参数整体作为一个元素添加进集合中---s.add(参数)
s.add("45") # {'45', 'C', 'F', 'P', 'h', 'i', 'n', 'o', 's', 't', 'y'}
- 集合的计算
💡集合的计算,s.intersection_update(*others),s.difference_update(*others),s.symmetric_difference_update(*others)
👉关于union_update,因为使用比较多,直接表示为update
s = set("FishC")
s.update([1,1],"23") # {1, '2', '3', 'C', 'F', 'h', 'i', 's'}
s.intersection_update("FishC") # {'C', 'F', 'h', 'i', 's'}
s.difference_update("Php","Python") # {'C', 'F', 'i', 's'}
s.symmetric_difference_update("Python") # {'C', 'F', 'P', 'h', 'i', 'n', 'o', 's', 't', 'y'}
- 删除指定元素
💡两种方法:s.remove(参数)、s.discard(参数)
👉区别是,前者删除的内容不存在会抛出异常,后者删除的内容不存在有一个静默处理
s.remove("Php") # 抛出异常
s.discard("Php") # 没有任何处理
-
随机从集合中弹出一个元素---s.pop()
👉因为存储的顺序是随机的,虽然在弹出时是按照顺序来的,但其实就是随即弹出一个元素
s.pop() # 'F'
s.pop() # 'h'
- 集合的长度---len(s)
- 清空集合---s.clear()
3、集合的遍历
for i in Hero:
print(i,end=' ') # 东皇 小鲁班 鲁大
4、判断元素存在与否 in() not in()
'C' in s # True
5、拷贝
s = set([1,2,3,4,5])
t = s.copy()
6、判断集合与一个可迭代对象是否相关
💡集合.isdisjoint(可迭代对象)
👉False代表相关,元素有交集;True代表确实是不相关的
s = set("python")
s.isdisjoint(set("FishC")) # 并不是毫不相关,有交集'h' False
s.isdisjoint(set("JAVA")) # True
7、集合的嵌套
💡因为集合是一个可变的无序对象,不能通过简单的包含进行嵌套。考虑到frozenset()的不可变性,可以使用其创建一个不可变对象,然后再将其嵌套进别的集合
s = frozenset("fishc")
y = {s,4,5} # {4, 5, frozenset({'c', 'f', 'h', 'i', 's'})}
(四)集合推导式
{s for s in "FishC"} # {'C', 'F', 'h', 'i', 's'}
五、python推导式
💡是一种独特的数据处理方式,可以从一个数据结构序列构建另一个新的数据结构序列的结构体
👉python支持列表、元组、字典、集合推导式
附:可哈希
💡可哈希:如果一个对象是可哈希的,那么就要求它的哈希值在其程序的整个生命周期都是不变的
👉可使用hash()函数获取哈希值
- 对整数进行哈希,它的值等于本身
- 如果两个对象的值是想等的,那么它们的哈希值是相等的
- 对于可变类型的数据不能获得哈希值
hash(1) # 1
hash(1.0) # 1
hash(2) # 2
hash([1,2,3]) # 抛出异常
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!