17数据容器
17.1介绍
1.数据容器是一种数据类型,有些地方也简称为容器/collections 2.数据容器可以存放多个数据,每一个数据也被称为一个元素 3.存放的数据/元素可以是任意类型 4.简单的说,数据容器就是一种可以存放多个数据/元素的数据类型
17.2分类
列表、元组、字符串、集合、字典
17.3列表
17.3.1列表介绍
列表可以存放多个不同类型数据,即:列表就是一列数据(多个数据) 列表也是一种数据类型
17.3.2列表的定义
创建一个列表,只要用逗号分隔的不同的数据项使用方括号括起来即可,示例如下:
list1 = [100,2,30,40,500]
列表索引从0开始
17.3.2列表使用语法
列表名[索引] list = ['q','b','w','t'] 访问第三个元素list[2]
17.3.2列表遍历(
就是将列表的每个元素依次取出,进行处理的操作,就是遍历/迭代
17.3.4列表使用细节
1.如果我们需要一个空列表,可以通过[],或者st()方式来定义 list1 = [] list2 =list() 2.列表的元素可以有多个,而且数据类型没有限制(可以混合),允许有重复元素,并且是有序的(元素取出的顺序和存放的顺序一致) list3 =[100,100,"apple",5.3,ture] 嵌套列表 list4 = [100,'tom',["tianlo",50,True]] print(list4) 3.列表的索引/下标是从0开始的 4、列表索引必须在指定范围内使用,否则报:IndexError:list index out of range list =[1,33,5.5] print(list[3]) #会报错 5.索引也可以从尾部开始,最后一个元素的索引为-1,往前一位为-2,以此类推(也不能超出范围) list = [1,22,5.5] list[-1] print(list[-4])#会报错 6、通过列表[索引]=新值对数据进行更新,使用列表.append(值)方法来添加元素,使用deI语句来删除列表的元素,注意不能超出有效索引范围 list_a = ['apple','orange'] list_a[0] ='white'#['white','orange'] list_a.append('black')#list_a ['white', 'orange', 'black'] del list_a[1]#list_a ['white', 'black'] 7.列表是可变序列(要注意其使用特点) 列表的元素是可以修改的,修改后,列表变量指向地址不变,只是数据内容变化 list1 = [1,2,'apple'] print(f"list1:{list1} 地址:{id(list1)} {list1[2]} {id(list1[2])}") list1[2] = 'python' print(f"list1:{list1} 地址:{id(list1)} {list1[2]} {id(list1[2])}") 结果: list1:[1, 2, 'apple'] 地址:2440612347328 apple 2440614139088 list1:[1, 2, 'python'] 地址:2440612347328 python 2440611937280
注意指的是0x1122不变
通过list2会影响list1,如下图,更改list2,会改变list1
#扩展一下,看看列表在函数传参时的特点,示意图 函数内修改参数会影响函数外的输出 def f1(L): 1[0]=100 print("L的id:",id()) 1ist10=[1,2.1,200] print("List10id:"id(list10)) f1(1ist10) print("1ist10:",1ist10)#输出? 1ist10的id:1838428115200 1的1d:1838428115200 11st10:[100,2.1,200]
17.3.5列表的常用操作
可变序列操作
list_a = [100,200,300,400,300] len(list):列表元素个数 max(list):返回列表元素最大值 min(list):返回列表元素最小值 list(seq):将元组转换为列表 list.append(obj):在列表末尾添加新的对象 ist.append(900) list.count(obj):统计某个元素在列表中出现的次数 list_a.count(100) list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) list_a.extend(list_b) list.index(obj):从列表中找出某个值第一个匹配项的索引位置(就是找到list.index(300)在列表中第一次出现的位置:2,如果没有报错ValueError) list.insert(index,obj):将对象插入列表将对象插入列表指定的index位置 list_a.insert(1,666)#把666插入到index为1的位置 list.pop([index:=-1]):移除列表中的=个元素(默认最后一个元素),并且返回该元素的值 list.remove(obj):移除列表中某个值的第一个匹配项 list.reverse():反向列表中元素(逆序) eg:list_a.reverse()#结果[300,400,300,200,100] list.sort(key=None,reverse=False:对原列表进行排序 list.clear():清空列表 list.copy():复制列表
17.3.6列表生成式
列表生成式就是生成列表的公式
语法
[列表元素的表达式 for 自定义变量 in 可迭代对象] [ele *2 for ele in range(1,5)]===>得到列表[2,4,6,8]
17.4元组
元组(tuple)可以存放多个不同类型数据,元组是不可变序列``允许有重复元素
tuple不可变是指当你创建了tuple时候,它就不能改变了,也就是说它也没有append(),insert()这样的方法但它也有获取某个索引值的方法,但是不能重新赋值 tuple_c = (1,2,3,4,5,6,7,8)
17.4.1元组的使用
比如:你要使用tuple.c元组的第3个值"blue",则通过tuple.c[2]就可以访问到 老韩提示:注意索引是从0开始计算的
17.4.2元组的遍历
将元组的每个元素依次取出,进行处理的操作,就是遍历/迭代
17.4.3元组使用注意事项
使用一对圆括号来表示空元组:() 使用一个后缀的逗号来表示单元组:a,或(a,) 使用以逗号分隔的多个项:a,b,c,or(a,b,c) 使用内置的tuple():tuple()或tuple(iterab1e) 1.如果我们需要一个空元组,可以通过(),或者tuple()方式来定义 2.元组的元素可以有多个,而且数据类型没有限制(甚至可以嵌套元组),允许有重复元素,并且是有序的 tuple_s = (100,"tom",("jack",200,'asd')) 3、元组的索引/下标是从0开始的 4、元组索引必须在指定范围内使用 5、元组是不可变序列 tuole_a[2] = 'apple' #❌ 6、可以修改元组内list的内容(包括修改、增加、删除等) eg:tuple_a =(1,2,'ww',[1,33,"apple"]) tuple_a[3][2]="orange"#√ tuple_a[3]=[10,20,30] #❌ del tuple_a[3][0]#√ del tuple_a[3] #❌ tuple_a[3].append('orange')#√ tuple_a.append("orange") #❌ 7、索引也可以从尾部开始,最后一个元素的索引为-1,往前一位为-2以此类推 tuple_a[-1] 8、定义只有一个元素的元组,需要带上逗号 tuple_h (100) 这样写类型是int tuple_h(100,)这样写类型是tuple 9.既然有了列表,python设计者为什么还提供元组这样的数据类型呢 --1在项目中,尤其是多线程环境中,有经验的程序员会考虑使用不变对象(一方面因为对象状态不能修改,所以可以避 免由此引起的不必要的程序错误;另一方面一个不变对象自动就是线程安全的,这样就可以省掉处理同步化的开销。可 以方便的被共享访问)。所以,如果不需要对元素进行添加、删除、修改的情况下,可以考虑使用元组 --2元组在创建时间和占用的空间上面都优于列表 --3元组能够对不需要修改的数据写保护
17.4.3元组常用操作
tuple_a =(100,300,200,100,500) len(tuple_a):元组元素个数 5 max(tuple_a):返回元组元素最大值 500 min(tuple_a):返回元组元素最小值 100 tuple.count(100):统计某个元素在元组中出现的次数 2 tuple.index(200):从元组中找出某个值第一个匹配项的索引位置 1 print(300 in tuple_a) 结果True
17.5字符串
17.5.1基本介绍
1.在Python中处理文本数据是使用str对象,也称为字符串。字符串是由Unicode码位构成的不可变序列
Unicode:65536个字符 ord()返回单个字符对应的Unicode编码值 ord("a) #字符对应的码值97
2.字符串字面值有三种写法
1)单引号:允许包含有"双”引号 2)双引号:"允许嵌入单'引号" 3)三重引号:“"三重单引号",""三重双引号"”,使用三重引号的字符串可以跨越多行一一其中所有的空白字符 都将包含在该字符串字面值中
3、字符串是字符的容器,一个字符串可以存放多个字符,比如"hello,niyao"
17.5.2字符串支持索引
字符串名[索引] string_a = "red-green" print("str_a的第三个值/字符是:",str_a[2],"类型是:",type(str_a[2]) # d str
17.5.3字符串的遍历
简单的说,就是将字符串的每个元素依次取出,进行处理的操作,就是遍历/迭代
str_a='sadfhioi' index = 0 while index < len(str_a): print(f"第{(index+1)}个元素是:{str_a[index]}") index += 1
17.5.4字符串的注意事项和使用细节
1、字符串索引必须在指定范围内使用,否则报:IndexError:string index out of range,比如str_d="hi-nihao"有效下标为0-7,索引也可以从尾部开始,最后一个元素的索引为-1,往前一位为-2,以此类推 2、字符串是不可变序列,不能修改,看下面的代码 string_a = "red-green" str[3]="q" #❌ 3、在Python中,字符串长度没有固定的限制,取决于计算机内存大小
17.5.5字符串常用操作一览
str_name = "tom jack mary jone jack" len(str):字符串的长度,也就是包含多少个字符 str.replace(old,newL[,count]):返回字符串的副本,其中出现的所有子字符串old都将被替换为new。 如果给出了可选参数count,则只替换前count次出现 str_name_new = str_name.replace("jack","杰克",1) #结果是:tom 杰克 mary jone jack str_name.replace("jack","杰克")#默认全部替换 str.split(sep=None,maxsplit=-1): 1.返回一个由字符串内单词组成的列表,使用sep作为分隔字符串。 2.如果给出了maxsplit,则最多进行maxsplit次拆分(因此,列表最多会有maxsplit-+1个元素)。 3.如果maxsplit未指定或为-1,则不限制拆分次数(进行所有可能的拆分) #需求对str_names按照""进行分割 str_name_split = str_name.split(" ") #返回的还是副本 #结果是:str_names_split内容是['tom', 'jack', 'mary', 'jone', 'jack']类型是:<class 'list'> str.count(sub):统计指定字符串在字符串中出现的次数 str.index(sub):从字符串中找出指定字符串第一个匹配项的索引位置 print(f"tom出现的索引是:{str_name.index('tom')}") # 结果是:0 str.strip([chars]):返回原字符串的副本,移除其中的前导和末尾字符。chars为指定要移除字符的字符串 eg: str2 = " 111acc ada " print(str2.strip(" "))#结果是:111acc ada str2 = "1341acc 1443ada 143" print(str2.strip("134"))#结果是:acc 1443ada str.lower():返回原字符串小写的副本 str_xiao = "asdASDWFQ" print(str_xiao.lower())#结果是:asdasdwfq str.upper():返回原字符串大写的副本 print(str_xiao.lower())#结果是:ASDASDWFQ 注意:!!!返回字符串的副本表示原来的字符串不变,而是返回一个新的字查串,
17.5.6字符串比较
1)运算符:>,>=,<,<=,==,!= 2)比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较 3)比较原理:两个字符进行比较时,比较的是其ordinal value(原始值/码值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符 chr(49) 对应 1 print(chr(23432)) 对应 守
17.6切片
从一个序列中,取出一个子序列,在实际开发中,程序员经常对序列进行切片操作
序列是指,内容连续、有序,可使用索引的一类数据容器
我们前面学习过的,列表(Iist)、元组(tuple)、字符串均可视为序列
17.6.2基本语法
序列[起始索引:结束索引:步长] 1)表示从序列中,从指定的起始索引开始,按照指定的步长,依次取出元素,到指定结束索引为止,截取到一个新的序列 2)切片操作是前闭后开,也就是[起始索引:结束索引),即截取的子序列,包括起始索引,但是不包括结束索引的部分 eg: str = 'apple' str[0:3:1]#结果是:app 3)步长表示,依次取出元素的间隔 -步长为1:一个一个的取出元素 -步长为2:每次跳过一个元素取出 -步长为N:每次跳过N-1个元素取 str_slice = str[0:5:1] print(str_slice) #对列表进行切片 list_a = ["jack","tom","json","mary","hellen"] #需求截取['tom','mary'] list_slice =list_a[1:4:2] print(list_slice) #对元组进行切片 tuple_a = (1,2,3,4,5,6,7,8,9) #需求:截取(3,4,5,6) tuple_slice =tuple_a[2:6:1] print(tuple_slice)
17.6.3注意事项
1、切片语法:序列[起始索引:结束索引:步长],起始索引如果不写,默认为0,结束索引如果不写,默认为截取到结尾,步长如果不写,默认为1 2、切片语法:序列[起始索引:结束索引:步长],步长为负数,表示反向取,同时注意起始索引和结束索引也要反向标记 str = "123456" str[-1::-1]#结果是:654321 str[-1:-6:-2 ]#结果是:642 3、切片操作并不会影响原序列,而是返回了一个序列
17.7集合
17.7.1集合基本介绍
1.集合是由不重复元素
组成的无序
容器。
无序,也就是你定义元素的顺序和取出的顺序不能保证一致
集合底层会按照自己的一套算法来存情和取数据,所以每次取出顺序是不变的
2、集合对象支持合集、交集、差集等数学运算
3.在项目中,我们可能有这样的需求:需要记录一些数据,而这些数据必须保证是不重复的,而且数据的顺序并没有要求,就可以考虑使用集合
注意:列表、元组的元素是可以重复,而且有序
17.7.2集合定义
创建一个集合,只要用逗号分隔的不同的数据项,并使用{}括起来即可,示例如下:
jihe = {'tom','mary','jack'}
17.7.3注意事项
1.集合是不重复元素组成(会自动去重)的无序容器
2.集合不支持索引
set_a = {100,100,200,30,50,600} print(set_a[0]) #格式错误
3、既然集合不支持索引,所以对集合进行遍历不支持while,只支持for
set_a = {100,100,200,30,50,600} for ele in set_a: print(ele)
4.创建空集合只能用set() 不能用{},{}创建的是空字典
set_a ={} #定义的是字典 set_a = set()
17.7.4集合常用操作一览
set_a ={'100','200','300','400','500','100'} set_b = {'200','600','700'} 1.len(集合):集合元素个数 2.x in s:检测x是否为s中的成员 eg: 100 in set_a 结果是:True 3.add(elem):将元素elem添加到集合中 eg: set_a.add('900') 4.remove(elem):从集合中移除元素elem。如果elem不存在于集合中则会引发KeyError set_a.remove('300') 5.pop():从集合中随机移除并返回任意一个元素。如果集合为空则会引发KeyError set_a.pop() #注意会影响原先数据 6.clear():从集合中移除所有元素 7.union(*others): 返回一个新集合,其中包含来自原集合以及others指定的所有集合中的元素 (对集合求并集) set_c = set_a.union(set_b) ser_c = set_a | set_b 8.intersection(*others) 返回一个新集合,其中包含原集合以及others指定的所有集合中共有的元素(求交集) set_d = set_a.intersection(set_b) #结果{'200'} set_d = set_a&set_b #第二种写法 difference(*others): 返回一个新集合,其中包含原集合中在others指定的其他集合中不存在的元素(求差集) eg:求只在set_a中的元素 set_e = set_a.difference(set_b) set_e = set_a - set_b eg:求只在set_b中的元素 set_e = set_b.idfference(set_a) set_e = set_b - set_a
17.7.5集合生成式
1.集合生成式就是"生成集合的公式
2.基本语法
{集合元素的表达式 for 自定义变量 in 可迭代对象} {ele*2 for ele in range(1,5)} #结果是:{2,4,6,8}注意顺序不一这样 y
集合生成式和列表生成式的区别就在于,集合生成式使用{},而列生成式使用[]
17.8字典
1、目前这种需求是:通过x查询yy的需求 2、在编程中,我们通常称为基于Key查询Value场景需求,是经常遇到的,是一种映射关系 3、而前面学习的列表、元组、集合都是一种单值存储,处理映射关系就不方便了 4、解决方案->字典(dict)
17.8.1基本介绍
1、字典(dict,完整的单词是dictionary)也是一种常用的Python数据类型,其他语言可能把字典称为联合内存或联合数组 2、字典是一种映射类型,非常适合处理通过x查询yy的需求,这里的xx我们称为Key(键/关键字),这里的yy我 们称为alue(值),即Key--Value的映射关系
17.8.2字典的定义
创建一个字典,只要把逗号分隔的不同的元素,用{}括起来即可,存储的元素是一个个的:键值对,示例: dict_a {key:value,key:value,key:value....} -通过key取出对应的value语法: 字典名[key] eg:dict_a[key1]
dict_a ={'tom':18,'mary':20} print(f"dict_a:{dict_a} 类型:{type(dict_a)}") print("tom的年龄是:",dict_a['tom'])
17.8.3注意事项和使用细节
1.字典是以键进行索引的, 字典的Key(关键字)通常是字符串或数字,Value可以是任意数据类型(字典、元组、列表、集合、字符串。。。) 2、字典不支持索引,会报KeyError eg:dict_a = { "tom":[10,20,60] "jack":"266" } print(dict_a[0]) #错误语法正确的是dict_a["tom"] 3、既然字典不支持索引,所以对字典进行遍历不支葫while,只支打for #遍历方式1-依次取出key,再通过dict[key]取出对应的value for key in dict_b: print(f"key:{key} value:{dict_b[key]}") #遍历方式2-依次取value print("----遍历方式2-----") for value in dict_b.values(): print(f"value:{value}") #遍历方式3-依次取出key-value print("------遍历方式3------") for key,value in dict_b.item():#item()取键值对 print(f"key:{k} value:{v}") 4、创建空字典可以通过{},.或者dict() 5、字典的key必须是唯一的,如果你指定了多个相同的key,后面的键值对会覆盖前面的 dict_e {'one':1,'two':2,'three':3,'two':200} print(dict_e)#结果{'one': 1, 'two': 200, 'three': 3}
17.8.4字典常用操作
dict_a = {"one":1,"two":2,"three":3} 1.len(d):返回字典d中的项数 len(dict_a) #结果是3 2.d[key]:返回d中以key为键的项。如果映射中不存在key则会引发KeyError dict_a['three']#结果是3 dict_a['four']#结果是KeyError 3.d[key]=value:将d[key]设为value,如果key已经存在,则是修改value,如果key不存在,则是增加key-value dict_a['one'] = '一' dict_a['four'] = 4 4.del d[key]:将d[key]从d中移除。如果映射中不存在key则会引发KeyError del dict_a['four'] # del dict_a['five']#结果是KeyError 5.pop(key[,default]):如果key存在于字典中则将其移除并返回其值,否则返回default。如果default未给出且key不存在于字典中,则会引发KeyError val = dict_a.pop ('one') print(f'val:{val}') #"1" print(f'dict_a:{dict_a}') #结果是{"one":1,"two":2,"three":3} !!!因为pop影响原先的键值对 val = dict_a.pop ('non') #结果是KeyError val = dict_a.pop ('non',"哈哈") print(f'val:{val}')#结果是:val:哈哈 print(f'dict_a:{dict_a}')#原先的键值对无影响 {"one":1,"two":2,"three":3} 6.keys():返回字典所有的key dict_keys = dict_a.keys() print(f"dict_keys:{dict_keys}{type(dict_keys)}")#类型<class'dict_keys'> for k in dict_keys:4 print("k-->"),k 7.key in d:如果d中存在键key则返回True,否则返回False print("one" in dict_a #True 8.clear():移除字典中的所有元素 dict_a.clear()
17.8.字典生成式
内置函数zip() 说明:zip()可以将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,返回由这些元组组成的列表
{字典key的表达式:字典value的表达式for表示key的变量,表示value的变量in zip(可迭代对象,可迭代对象)}
books=["红楼梦”,"三国演义","西游记","水浒传"] authors=["曹雪芹","罗贯中","吴承恩","施耐庵"门 {book:author for book,author in zip(books,authors)}===> '红楼梦':'曹雪芹','三国演义':'罗贯中','西游记':'吴承恩','水浒传':'施耐庵'
给出两个列表: english list ["red","black","yellow","white"] chinese_list=["红色","黑色","黄色","白色"门 生成一个字典: '红色':'RED','黑色':'BLACK','黄色':'YELLOW','白色':'WHITE' 对应代码 dict_color {elel:ele2.upper()for elel,ele2 in zip(chinese_list,english_l)
数据容器小结
通用的转换操作
str_a = hello" list_a =["jack","tom","mary"] tuple_a= ("hsp","tim") set_a= {"red","black"} dict_a={"0001":"小倩","0002":"黑山老妖"} #iterable可以是序列、支持迭代的容器或其它可迭代对象 #也就是将指定的容器转成列表 print("-"*60) print(f"str_a转成list:{list(str_a)}")#["h","e","L","L",o] print(f"tuple_a转成list:{list(tuple_a)}")#["hsp","tim"] print(f"set_a转成list:{list(set_a)")#["red","black"] print(f"dict_a转成list:{list(dict_a)}" #['0001',0002']
其他操作
38_list_tuple_set_dict传参机制
list tuple set dict传参机制一样
def f1(my_list): print(f"f1() my_list: {my_list} 地址是:{id(my_list)}") my_list[0] = "jack" print(f"f1() my_list: {my_list} 地址是:{id(my_list)}") my_list = ["tom","jsos","sss"] print(f" my_list: {my_list} 地址是:{id(my_list)}") f1(my_list) # my_list: ['tom', 'jsos', 'sss'] 地址是:1969206776192 #f1() my_list: ['tom', 'jsos', 'sss'] 地址是:1969206776192 #f1() my_list: ['jack', 'jsos', 'sss'] 地址是:1969206776192
数据容器总结
1、python数据类型主要有整数int/浮点数float/字符串str/布尔值bool/元组tuple/列表Iist/字典 dict/集合set,数据类型分为两个大类,一种是可变数据类型;一种是不可变数据类型
2、可变数据类型和不可变数据类型 可变数据类型
:当该数据类型的变量的值发生了变化,如果它的内存地址不变,那么这个数据类型就是可变数据类型 不可变数据类型
:当该数据类型的变量的值发生了变化,如果它的内存地址改变了,那么这个数据类型就是不可变数据类型
3、python的数据类型 不可变数据类型:数值类型(int、float)、bool(布尔)、string(字符串)、tuple(元组) 可变数据类型:Iist(列表)、set(集合)、dict(字典)
注意切片
针对序列操作且支持索引的数据类型
序列是指,内容连续、有序,可使用索引的一类数据容器
我们前面学习过的,列表(Iist)、元组(tuple)、字符串均可视为序列
字典与集合不支持索引所以不能切片