一、数据结构
1.list:常用
变量:相当于是一个容器,每次只能存储一个数据
作用:相当于是一个容器,可以同时存储多个数据
本质:一种有序的集合【有序:数据的存放顺序和底层存储的顺序是相同】
列表中的元素本质存储的是一个变量【引用】,列表是可变的【一个列表一旦被定义,则在代码运行的过程中,其中的元素的值可以随时发生改变】
num = 10
list1 = [43,5,45,46,5]
print(id(list1[0]))
list1[0] = 100
#1.创建【定义一个列表类型的变量】 #命名方式:lxx listxxx,不建议直接使用list #其中允许存放重复元素 list1 = [45,23,2,54,54,6] print(list1) #其中允许存放不同类型的数据 list2 = ["hello",4637,False] print(list2) #列表元素的访问 #索引/下标/角标:取值范围:0~len(xx) - 1 或者 -1~ - (len(xxx)) print(list1[3]) print(list1[-1]) #print(list1[20]) #IndexError: list index out of range 列表下标越界 #列表元素的替换/修改 list1[3] = 473 print(list1) #组合:生成了一个新的列表 print(list1 + list2) print(list1) #列表元素的重复 print(list1 * 3) print(list1) #判断某个元素是否在列表中 print(10 in list1) #False print(10 not in list1) #True print(45 in list1) #True print(45 not in list1) #False #列表切片【截取】:根据指定的列表获取子列表 list3 = [45, 23, 2, 473, 54, 6,5,6,56,5] print(list3[2]) print(list3) #格式:列表名[start:end:step],包头不包尾 #获取从指定下标开始到结尾的元素组成的一个子列表 print(list3[2:]) #获取从开头到指定下标的元素。。。。 print(list3[:6]) #截取指定区间 print(list3[2:6]) #特殊情况1:如果end超出了下标的范围,则默认获取从指定下标开始到结尾的元素 print(list3[4:100]) #等价于 print(list3[4:]) #特殊情况2:step在默认情况下为1 print(list3[1:6:2]) #1,3,5 print(list3[-1:-6]) #当start和end都为负数,step为正数的时候,获取的结果为[] print(list3[-1:-6:-2]) #当start,end和step都为负数的时候,表示倒序 #将列表倒序输出 print(list3[-1::-1]) print(list3[::-1]) #列表系统功能 #1.添加元素 #1.1append,追加,在列表的末尾添加元素 常用 l1 = [22,33,44,55] print(l1) #追加单个元素 l1.append(66) print(l1) #追加多个元素,不能直接追加,通过列表的形式追加,形成了一个二维列表 #l1.append(77,88) #报错:TypeError: append() takes exactly one argument (2 given) l1.append([77,88]) print(l1) #结果:[22, 33, 44, 55, 66, [77, 88]] #1.2extend,扩展,在列表的末尾添加元素 l2 = [22,33,44,55] #追加单个元素,不能直接添加,参数一定是可迭代的 #l2.extend(66) #T报错:ypeError: 'int' object is not iterable l2.extend([66]) print(l2) l2.extend([77,88]) print(l2) #结果:[22, 33, 44, 55, 66, 77, 88] """ 总结: 列表名.功能名(xx) append可以直接添加单个元素,而extend不能 append在添加多个元素的时候,是以列表的形式添加,而extend只添加元素【打碎加入】 """ #1.3insert,插入,在指定索引处插入一个元素,后面的元素向后顺延 #列表名.insert(索引,被插入的元素) l3 = [22,33,44,55] #插入单个元素 l3.insert(2,66) print(l3) #插入多个元素:和append类似,将整个列表直接插入 l3.insert(1,[77,88]) print(l3)
#2.删除 #2.1pop,弹出,移除并获取列表中指定索引处的元素 在栈中【列表的底层工作原理是栈】 list1 = [11,22,33,44,55] #注意:pop在默认情况下删除的是最后一个元素 result1 = list1.pop() print(list1) print(result1) result2 = list1.pop(2) print(list1) #2.2remove,移除,直接操作的是元素 list2 = [11,22,33,44,55,33,33,55] list2.remove(22) print(list2) #注意:移除指定元素在列表中第一次匹配到的元素【从左往右】 list2.remove(33) print(list2) #2.3clear 清除,将指定列表变为空列表 使用场景:循环中,每次需要清空【重置】列表 list2.clear() print(list2)
#3.获取 list1 = [54,6,57,5,57,7,6,7,57] #3.1len(),获取列表长度 l = len(list1) #3.2max(),获取列表中的最大值 print(max(list1)) #3.3min(),获取列表中的最小值 print(min(list1)) #练习:模拟max或者min的功能,求三个数中的最大值 #假设法 num1 = 43 num2 = 437 num3 = 2 #定义一个变量,用于记录最大值 max1 = num1 if num2 > num1: max1 = num2 if num3 > max1: max1 = num3 #3.4index(),获取指定元素在原列表中第一次匹配到的索引 print(list1.index(57)) #模拟index的功能 for i in range(len(list1)): if list1[i] == 57: print(i) #3.5count(),统计个数,统计指定元素在列表中出现的次数 c = list1.count(57) print(c) list1 = [54,6,57,5,57,7,6,7,57,57,57,436] #练习:将list1中57给全部删除 # list1.remove(57) # list1.remove(57) # list1.remove(57) # print(list1) #统计57在列表中出现的次数 num = 57 c = list1.count(num) n = 1 while n <= c: list1.remove(num) n += 1 print(list1)
import copy #4.其他用法 #4.1.reverse,反转 list1 = [35,4,5,4,654] #print(list1[::-1]) # list1.reverse() # print(list1) #4.2.1sort,排序,默认为升序,在列表内部进行排序 #列表名.sort() #升序 # list1.sort() # print(list1) #降序 # list1.sort(reverse=True) # print(list1) #4.2.2sorted,排序,默认为升序,生成了一个新的列表 #sorted(列表名) #升序 newList = sorted(list1) print(list1) print(newList) #降序 newList2 = sorted(list1,reverse=True) print(newList2) #根据元素的长度进行排序 list2 = ["gjsrghj","545","fhghg","ahjegrhkwjhgrke"] #key关键字参数可以指定自定义的排序规则,格式:key=函数名 newList3 = sorted(list2,key=len,reverse=True) print(newList3) #4.3copy,拷贝 #直接赋值,浅拷贝,栈空间层面上的拷贝【引用】 list1 = [23,54,56] list2 = list1 list2[1] = 100 print(list1) print(list2) print(id(list1) == id(list2)) #copy,深拷贝,堆空间层面上的拷贝【实体】 list1 = [23,54,56] list2 = list1.copy() list2[1] = 100 print(list1) print(list2) print(id(list1) == id(list2)) #模块copy ,copy(),deeepcopy()【面试题】 #内容角度上的拷贝,copy只拷贝最外层,deepcopy可以拷贝内层的内容【二维列表中】 a = [1,2,3] b = [4,5,6] c = [a,b] print(c) d = copy.copy(c) print(id(d) == id(c)) #False e = copy.deepcopy(c) print(id(e) == id(c)) #False a.append(4) print(c) print(d) #[[1, 2, 3, 4], [4, 5, 6]] print(e) #[[1, 2, 3], [4, 5, 6]] """ d:[[1, 2, 3], [4, 5, 6]] [list1,list2]---->list1:[1,2,3] list2:[4,5,6] """ #4.4转换 #list(),tuple() #二维列表:遍历 l1 = [[11, 22, 33, 44], [44, 55, 66]] print(l1[0]) #l1[0] = [11, 22, 33, 44] print(l1[0][2]) for i in l1: for j in i: print(j) for n1 in range(len(l1)): for n2 in range(len(l1[n1])): print(l1[n1][n2])
2.tuple
和列表类似,本质是一种有序的集合
元组和列表的不同之处:
a.定义不同:列表[] 元组()
b.是否能够修改:列表可以进行增加或者删除元素的操作,但是,元组一旦被定义之后,其中的元素将不能进行任何的更改
#其中允许存储重复元素 t1 = (23,53,54,53) print(t1) #其中允许存储不同类型的数据 t2 = ("hello",47,19.0,False) print(t2) #特殊情况:当一个元组中只有一个元素的之后,会被识别为一个普通变量 t3 = (10) print(type(t3)) print(t3) #为了消除歧义,当元组中只有一个元素的时候,元组名 = (元素,) t4 = (10,) print(type(t4)) print(t4) #元组元素的访问 #元组名[索引] print(t2[1]) #t2[1] = 100 #报错:TypeError: 'tuple' object does not support item assignment【赋值】 #特殊情况:如果在元组中的元素是列表,则列表中的元素依旧可以修改 # 【依据:元组和列表中存储都是变量的地址,元素不允许修改,只需要保证未发生改变即可其中的地址】 t5 = (23,5,3,5,[235,345,5,45,4]) print(t5) print(t5[4]) #[235,345,5,45,4] t5[4][1] = 100 print(t5) #列表和元组的遍历 #直接获取元素 for element in t5: print(element) #获取索引 for i in range(len(t5)): print(i,t5[i]) #同时遍历索引和元素 #需要将元组或者列表转换为枚举类型 #list(t5) #注意:下面的i并不是元组或者列表的索引,而是枚举中的编号 for i,element in enumerate(t5): print(i,element)
3.dict:常用
也是一种存储数据的方式,但是字典是无序的,
类似于list或者tuple,但是,字典采用键-值对的方式存储数据
age1 = 10 list1 = [10,4,35,46,6] dict1 = {"zhangsan":10}
作用:具有极快的查找速度
键【key】相当于list或者tuple中的索引
key的特点
a.字典的key是唯一的【key不允许重复】
b.key必须为不可变的数据
list是可变的,不能用来当做key
tuple,数字型,字符串,布尔值都是不可变的,可以被充当key
dict1 = {"zhangsan":10,"lisi":13,"zhaoliu":50} #1.访问键值对 print(dict1["lisi"]) #访问一个不存在的key,则报错 #print(dict1["abc"]) #KeyError: 'abc' #字典是可变的 dict1["zhaoliu"] = 100 result0 = dict1["zhaoliu"] print(result0) #字典名[key] = value #注意:如果key存在,则表示修改value的值;如果key不存在,则表示在字典中添加一对新的键值对 dict1["abc"] = 20 print(dict1) #get() result1 = dict1.get("zhaoliu") print(result1) #如果key不存在,则不会报错,返回None,一般用于判断 result2 = dict1.get("def") print(result2) #2.删除,pop #注意:删除指定的key,对应的value也会随着删除 dict1.pop("lisi") print(dict1) #3.字典的遍历 #3.1直接遍历key 掌握 for key in dict1: print(key,dict1[key]) # print(dict1.keys()) # print(type(dict1.keys())) #<class 'dict_keys'> for key in dict1.keys(): print(key,dict1[key]) #3.2直接遍历value for value in dict1.values(): print(value) #3.3,遍历的是键值对的编号和key for i,element in enumerate(dict1): print(i,element) #3.4同时遍历key和value 掌握 for key,value in dict1.items(): print(key,value) """ 【面试题:dict和list之间的区别】 1.dict查找和插入的速度不会因为key-value的增多而变慢, 而list在每次查找的时候都是从头到尾进行遍历,当数据量大的时候,list速度肯定会变慢 2.dict需要占用大量的内存空间,内存浪费多, 而list只相当于存储了字典中的key或者value,并且list数据是紧密排列的 """
练习:
"""" 1.逐一显示列表l1 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]中索引为奇数的元素 2.将属于列表l1 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], 但不属于列表l2 = ["Sun","Mon","Thu","Fri","Sat"]的所有元素定义为一个新列表l3 3.已知列表namelist=['stu1','stu2','stu3','stu4','stu5','stu6','stu7'],删除列表removelist=['stu3', 'stu7', 'stu9']; 请将属于removelist列表中的每个元素从namelist中移除(属于removelist,但不属于namelist的忽略即可); 4.有一个字符串是一句英文,统计每个单词出现的次数,生成一个字典,单词作为key,次数作为value生成一个字典dict1 5.已知列表list1 = [0,1,2,3,4,5,6],list2 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], 以list1中的元素作为key,list2中的元素作为value生成一个字典dict2 """ #1. l1 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"] for i in range(len(l1)): if i % 2 != 0: print(l1[i]) #2. #思路:遍历l1,获取l1中的元素,判断在l2中是否存在,如果不存在,则添加到一个新的列表中 l1 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"] l2 = ["Sun","Mon","Thu","Fri","Sat"] l3 = [] for ele1 in l1: if ele1 not in l2: l3.append(ele1) #3 #思路:遍历removelist,获取其中的元素,判断该元素在namelist中是否存在,如果存在,则删除 namelist=['stu1','stu2','stu3','stu4','stu5','stu6','stu7'] removelist=['stu3', 'stu7', 'stu9'] for ele2 in removelist: if ele2 in namelist: namelist.remove(ele2) print(namelist) #4 str1 = "today is a good day today is a bad day today is a nice day" dict1 = {} #使用空格切割字符串 list1 = str1.split(" ") print(list1) #遍历列表,获取其中的每个单词 for word in list1: #在字典中通过key获取value c = dict1.get(word) if c == None: #不存在,添加键值对 dict1[word] = 1 else: #存在,则将value的值递增1 dict1[word] += 1 print(dict1) #5. list1 = [0,1,2,3,4,5,6] list2 = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"] dict2 = {} #定义一个变量,作为list1和list2的索引 index1 = 0 if len(list1) == len(list2): while index1 < len(list1): #dict2[key] = value =======>dict2[list1中的元素] = list2中的元素 #list1[index1] list2[index1] dict2[list1[index1]] = list2[index1] index1 += 1 elif len(list1) > len(list2): while index1 < len(list2): dict2[list1[index1]] = list2[index1] index1 += 1 else: while index1 < len(list1): dict2[list1[index1]] = list2[index1] index1 += 1 # 优化上面的代码:封装【抽取】 """ def custom(num): dict2[list1[num]] = list2[num] num += 1 return num #定义一个变量,作为list1和list2的索引 index1 = 0 if len(list1) == len(list2): while index1 < len(list1): #dict2[key] = value =======>dict2[list1中的元素] = list2中的元素 #list1[index1] list2[index1] r = custom(index1) index1 = r elif len(list1) > len(list2): while index1 < len(list2): r = custom(index1) index1 = r else: while index1 < len(list1): r = custom(index1) index1 = r """ print(dict2)
4.set
集合:不允许重复元素,而且进行交集以及并集的运算
表示:{}
和dict之间的关系:set中只是存储了key
本质:无序且无重复元素的集合
#1.创建 #set() s1 = {23,45,6,7,89} print(s1) print(type(s1)) #掌握:去除列表中的重复元素 s2 = set([3,46,5,65,7,65,7]) print(s2) s3 = set((2,43,54,5,4,5)) print(s3) #{2, 4, 5, 43, 54} s4 = set({10:"a",20:"b"}) print(s4) #{10, 20} #2.set是可变的 #2.1添加 #add(),添加, set1 = {11,22,33,44,55} #单个元素 set1.add(66) print(set1) #如果元素存在,则添加失败,不报错 set1.add(55) #多个元素 #s1.add([77,88]) #TypeError: unhashable type: 'list' s1.add((77,88)) #s1.add({1:"a"}) #结论:在set中,使用add添加,则只能添加元组,不能添加list和dict print(s1) #update(),更新,update的参数只能是可迭代对象【打碎加入】 set2 = {11,22,33,44,55} #set2.update(66) #报错:TypeError: 'int' object is not iterable set2.update([66]) print(set2) set2.update((77,88)) print(set2) set2.update({"12":12,"13":13}) print(set2) set2.update("hgjhg") print(set2) #3.删除 set2.remove(77) print(set2) #4.交集和并集 s1 = {3,54,4,5,7} s2 = {3,54,4,8,90} #交集:&【按位与】 print(s1 & s2) #并集:|【按位或】 print(s1 | s2)