# 数据容器的讲解
"""
Python中的数据容器:
一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素,每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。
数据容器根据特点的不同,如:
· 是否支持重复元素
· 是否可以修改
· 是否有序
等
分为5类,分别是:
列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
"""
"""
列表的讲解:
列表的语法:
变量名称 = [元素1、元素2、元素3,....]
定义空列表
变量名称 = []
或者
变量名称 = list()
列表内的每一个数据,称之为元素
· 以[]作为标识
· 列表内每一个元素之间用,逗号隔开
· 列表可以一次存储多个数据,且可以为不同的数据类型,同时支持嵌套
通过下标索引取出列表中的值
语法:
列表[下标索引]
· 下标索引可以正向索引,比如0,1,2,3,4,5,是正着顺序取数,元素的第一个位置是0
· 也可以反向索引,比如-1,-2,-3,-4,-5,是反着顺序取数,元素的最后位置是-1
· 注意,超索引一样会报错哦~
列表的常见功能方法
· 查找某元素的下标索引
功能:查找指定元素在列表的正向下标索引,如果找不到,报错ValueError
语法:列表.index(具体元素值(注意不是索引))
· 修改特定位置(索引)的元素值:
语法:列表[下标索引] = 赋新值
· 在指定的下标索引插入元素:
语法:列表.insert(要插入的下标索引位置,插入元素值)
· 将指定元素,追加到列表的尾部:
语法:列表.append(元素)
语法2:列表.extend(其他数据容器) # 将其他数据容器的内容取出,依次追加到列表的尾部
· 删除元素:
语法1:del 列表[下标索引]
语法2:列表.pop(下标) # 此方法可以返回删除的元素,如 var = 列表.pop(下标)
语法3:列表.remove(具体元素值(注意不是索引)) # 删除某元素在列表中的第一个匹配项(从前往后)
· 清空列表
语法:列表.clear()
· 统计某元素在列表内的数量
语法:列表.count(具体元素值(注意不是索引))
· 统计列表内,有多少元素
语法:len(列表)
"""
list1=["abc","吵我IE","12"]
list2=[123,True,"测试",list1] # 列表为不同的数据类型,同时嵌套第二个列表
list3=["abc","csd","sd","abc","sd"]
print(list1)
print(list2)
print(list2[3]) # 通过正向下标索引取出数据
print(list2[-1]) # 通过反向下标索引取出数据
print(list2[-1][-2]) # 通过反向下标索引取出嵌套列表的数据(正向和上方的一致,只不过反向很少使用,这里特地标明!)
print(list2.index(123)) # 查找某元素的下标索引
list1[0] = "xyz" # 修改特定位置(索引)的元素值
print(list1)
list1.insert(2,"345") # 在指定的下标索引插入元素
print(list1)
list1.append("678") # 将指定元素,追加到列表的尾部(单个追加)
print(list1)
list1.extend(["9","10"]) # 将其他数据容器的内容取出,依次追加到列表的尾部(一批追加)
print(list1)
del list1[1] # 删除元素语法1
list1.pop(1) # 删除元素语法2
list1.remove("12") # 删除某元素在列表中的第一个匹配项
print(list1)
list1.clear() # 清空列表
print(list1)
print(list3.count("abc")) # 统计某元素在列表内的数量
print(len(list3)) # 统计列表中所有元素的数量
"""
列表功能练习
"""
list_work = [21,25,21,23,22,20]
list_work.append(31)
list_work.extend([29,33,30])
list_work_num1 = list_work[0]
print(f"第一个元素值是: {list_work_num1}")
list_work_num2 = list_work[-1]
print(f"最后一个元素值是: {list_work_num2}")
print(f"元素31在列表中的索引位置是: {list_work.index(31)}")
list4=["abc","csd","sd","abc","sd"]
list4.extend(list_work)
list4_count_num_while = 0
# 使用while循环遍历列表
while list4_count_num_while < len(list4):
print(f"while循环遍历列表list4,当前元素值:{list4[list4_count_num_while]} ")
list4_count_num_while += 1
# 使用for循环遍历列表
for i in list4:
print(f"for循环遍历列表list4,当前元素值: {i}" )
"""
遍历列表练习
"""
list_work2 = [1,2,3,4,5,6,7,8,9,10]
list_work3=[]
list_work4=[]
list_work2_count_num=0
while list_work2_count_num < len(list_work2):
if list_work2[list_work2_count_num] % 2 == 0:
list_work3.append(list_work2[list_work2_count_num])
list_work2_count_num+=1
print(f"while遍历列表练习: {list_work3}")
for i in list_work2:
if i% 2 == 0:
list_work4.append(i)
print(f"for遍历列表练习: {list_work4}")
"""
元组的讲解:
元组同列表一样,都是可以封装多个、不同类型的元素在内。
但最大的不同点在于:元组一旦定义完成,就不可修改。(只读列表)
当我们需要在程序内封装数据,又不希望封装的数据被篡改,那么元组就非常合适了。
元组的定义:
定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型
定义语法:
变量名称 = (元素1,元素2,元素3,元素4,....)
定义空元组:
变量名称 = ()
或者
变量名称 = tuple()
注意:定义元组只有一个数据时,这个数据后面要添加逗号
通过下标索引取出元组中的值
语法:
元组[下标索引]
元组的常见功能方法
· 查找某元素的下标索引
功能:查找指定元素在元组的正向下标索引,如果找不到,报错ValueError
语法:元组.index(具体元素值(注意不是索引))
· 统计某元素在元组内的数量
语法:元组.count(具体元素值(注意不是索引))
· 统计元组内,有多少元素
语法:len(元组)
while和for循环和上方的列表使用一致
"""
tuple1 = ("abc",212,True) # 定义元组
tuple2 = ("def",) # 定义只有一个元素的元组,注意,必须带有逗号,否则不是元组类型!!
tuple3 = (tuple1,list_work2) # 嵌套元组,元素可以任意,放了列表同样支持,只是第2个元素为列表类型,但是整个元组不能修改
print(tuple3)
tuple4 = (tuple1,tuple2) # 嵌套元组,元素可以任意
print(tuple3[1][5]) # 取出嵌套元组中,列表的值
print(tuple4[1][0]) # 取出嵌套元组的值
tuple3[1][0] = 999
print(f"嵌套元组中的列表可以被修改,{tuple3}") # 元组不能被修改,但是有个特例:嵌套在元组里面的列表可以被修改~
# 元组小练习
tuple5=("xxx",11,["football","music"])
print(tuple5.index(11))
print(tuple5[0])
tuple5[2].pop(0)
tuple5[2].append("coding")
print(tuple5)
"""
字符串是字符的容器,一个字符串可以存放任意数量的字符。
字符串只允许存储字符串类型
和其他容器如:列表、元组一样,字符串也可以通过下标进行访问的。
· 从前向后,下标从0开始。
· 从后向前,下标从-1开始。
同元组一样,字符串是一个:无法修改的数据容器。
修改、移除、追加都是不允许的,只能重新赋值
字符串的常见功能方法
· 查找某元素的下标索引
功能:查找指定元素在字符串的正向下标索引,如果找不到,报错ValueError
语法:字符串.index(具体元素值(注意不是索引))
· 统计某元素在字符串内的数量
语法:字符串.count(具体元素值(注意不是索引))
· 统计字符串内,有多少元素
语法:len(字符串)
· 字符串的替换:
语法:字符串.replace(字符串1,字符串2)
功能:将字符串内的全部: 字符串1 ,替换为字符串2,得到一个新的字符串,可以使用变量接收
注意:不是修改字符串本身,而是得到了一个新字符串哦
· 字符串的分割
语法:字符串.split(分隔符字符串)
功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并返回列表类型的数据容器。
注意:字符串本身不变,而是得到了一个列表对象
· 字符串的规整操作(去前后空格)
语法:字符串.strip()
· 字符串的规整操作(去前后指定字符串)
语法:字符串.strip(指定去除字符串)
while和for循环和上方的列表使用一致
"""
str1="12sd 12s4 5d"
print(str1[1]) # 通过下标获取字符串中的某个元素
print(str1.index("5d")) # 查找某元素的下标索引
str2=str1.replace("12s4","abcyes") # 字符串的替换,使用变量接收,当然也可以使用原变量接收!
print(str2)
# 字符串的分割,这里使用空格来作为分隔符,一般分隔符为一个的话习惯使用char单引号,一个以上则使用双引号,并返回列表类型的数据容器。
list5 = str2.split(' ')
print(list5)
str3=" ..#iwejw.hjhk# "
str4 = str3.strip() # 字符串的规整操作(去前后空格)
print(str4)
# 字符串的规整操作(去前后指定字符串,这里指定的是"#.")注意:#.的意思是"."和"#"都会被消除,是按照单个字符来消除的,可以不按照顺序来
# 但是匹配到不符合的字符串时,就会结束当前方向的匹配。
# 匹配成功后,只要前方一个元素位置还有需要去除的字符串,也会一并去除,直到下一个元素位置不是指定字符串为止!
# 例如 "..#iwejw.hjhk#".strip("#.") 这样去除后,新的字符串为:iwejw.hjhk
# 可以看到,中间的'.'并没有被去除,因为无论是前方的i还是后方的k都不是指定的字符串,自然规整方法就终止了。
str5 = str4.strip("#.")
print(str5)
print(str5.count('.')) # 统计某元素在字符串内的数量
print(len(str5)) # 统计字符串内,有多少元素
# 分割字符串练习
str_work1="itheima itcast boxuegu"
print(f"it在字符串中出现了: {str_work1.count("it")}次")
str_work2 = str_work1.replace(' ','|')
print(str_work2)
str_work_list1=str_work2.split('|')
print(str_work_list1)
"""
序列讲解
序列是指:内容连续、有序,可使用下标索引的一类数据容器
列表、元组、字符串,均可以视为序列。
序列常用操作-切片:
序列支持切片,既:列表、元组、字符串,均支持进行切片操作
切片:从一个序列中,取出一个子序列
语法:序列[起始下标:结束下标:步长]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结,得到一个新序列:
· 起始下标表示从何开始,可以留空,留空视作从头开始。
· 结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾。
· 步长表示:依次取元素的间隔。
· 步长1表示:一个个取元素。
· 步长2表示,每次跳过一个元素取。
· 步长N表示,每次跳过N-1个元素取。
· 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
注意:切片操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)!
"""
list6=["abc","123","xyz","ABC","PPP"]
list7 = list6[1:4] # 步长1可以不写,所以是从索引1取到索引3(不含4!)
print(list7)
tuple6=("abc","123","xyz","ABC","PPP")
tuple7 = tuple6[1:4:2] # 从1开始,3结束,步长为2
print(tuple7)
str6="abc 123 xyz ABC PPP"
str7 = str6[::-1] # 反向从头开始,步长为1,等于反转序列
print(str7)
list7 = list6[-2:-5:-1] # -2开始,-4结束,步长为-1
print(list7)
tuple7 = tuple6[:-6:-3] # 反向从头开始,-5结束,步长为-3
print(tuple7)
# 切片案例:获取str8字符串的:"进程已结束" 字符串
str8 = "0为码代出退,束结已程进"
str8 = str8[::-1]
print(str8[:5])
"""
集合讲解
基本语法:
变量名称 = {元素1,元素2,元素3...}
定义空集合
变量名称 = set()
因为集合是无序的,所以集合不支持:下标索引访问。
但是集合和列表一样,是允许修改的。
集合常用操作:
· 添加新元素:
语法:集合.add(元素)。将指定元素,添加到集合内。
结果:集合本身被修改,添加了新元素。
· 移除元素:
语法:集合.remove(元素),将指定元素,从集合内移除
结果:集合本身被修改,移除了元素。
· 从集合中随机取出元素
语法:集合.pop()
功能:从集合中随机取出一个元素。
结果:会得到一个元素的结果。同时集合本身被修改,元素被移除!!
· 清空集合
语法:集合.clear()
· 取出2个集合的差集
语法:集合1.difference(集合2)
功能:取出集合1和集合2的差集(集合1有而集合2没有的)
结果:得到一个新集合,集合1和集合2不变!!
· 消除2个集合的差集
语法:集合1.difference_update(集合2)
功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素
结果:集合1被修改,集合2不变。
· 2个集合合并
语法:集合1.union(集合2)
功能:将集合1和集合2组合成新集合
结果:得到新集合,集合1和集合2不变
· 统计集合内,有多少元素
语法:len(集合)
· 集合不支持下标索引,所以不能使用while循环遍历,但是可以使用for循环遍历!!
"""
set1={"就会手机号","说的好几块十几块的",112233,112233,556677} # 定义集合,重复元素的将会被去除
print(set1)
set1.add(889900) # 添加新元素
print(set1)
set1.remove("说的好几块十几块的") # 移除元素
print(set1)
set_var=set1.pop() # 从集合中随机取出元素
print(f"集合 {set1} 取出的值为:{set_var},类型为{type(set_var)}")
set1.clear() # 清空集合
print(set1)
set1={"就会手机号","说的好几块十几块的",112233,"hjash",556677}
set2={"11","22","33",112233,"就会手机号"}
set3 = set1.difference(set2) # 取出集合1和集合2的差集(集合1有而集合2没有的)
print(set3)
set1.difference_update(set2) # 对比集合1和集合2,在集合1内,删除和集合2相同的元素
print(set1)
set4 = set1.union(set2) # 将集合1和集合2组合成新集合
print(f"长度:{len(set4)},集合:{set4}")
for i in set4: # 集合不支持下标索引,所以不能使用while循环遍历,但是可以使用for循环遍历
print(i)
# 集合小练习
list_work5=["黎明方舟","DA","xxx","黎明方舟","DA","xxx","反方向的猫","寰宇","反方向的猫"]
set5=set()
for i in list_work5:
set5.add(i)
print(set5)
"""
字典的讲解
字典的定义,同样使用{},不过存储的元素是一个个的:键值对,如下语法:
变量名称 = {key:value, key:value, ......, key:value}
定义空字典:
变量名称 = {}
或者
变量名称 = dict()
字典同集合一样,不可以使用下标索引
但是字典可以通过key值来取得对应的value
语法如下:
value = 字典[key]
字典的key和value可以是任意数据类型(key不可为字典!)
那么,就表明,字典是可以嵌套的
字典的常用操作:
· 新增元素:
语法:字典[key] = value
结果:字典被修改,新增了元素
· 更新元素
语法:字典[key] = value
结果:字典key不可以重复,所以对已存在的key执行上述操作,就是更新value值!!
简单来说,key无法更改,但是对应的value可以更改!
· 删除元素
语法:字典.pop(key),结果:获得指定key的value,同时字典被修改,指定key的数据被删除
· 清空字典
语法:字典.clear(),结果:字典被修改,元素被清空。
· 获取字典中全部的key(注意:是key而不是value)
语法:字典.keys()
结果:得到字典中的全部key
· 统计字典内,有多少元素
语法:len(字典)
"""
dict1 = {"xxx":"黎明方舟","成龙":"警察故事","周星驰":"家有喜事"}
print(f"字典 {dict1},取出键值对的方法是:{dict1["成龙"]}") # 通过key值来取得对应的value
# 字典的key和集合一样,都是不允许重复的哦~
# 如果有重复的话,会使用最后面的那个键值对!
dict2 = {"xxx":"黎明方舟","成龙":"警察故事","周星驰":"家有喜事","xxx":"DA"}
print(dict2)
# 嵌套字典
dict3 = {
"小红":{"语文":77,"数学":66,"英语":33},
"小明":{"语文":88,"数学":86,"英语":55},
"小芳":{"语文":99,"数学":96,"英语":66}
}
print(dict3["小红"]["英语"]) # 获取嵌套字典的值
dict3["小李"] = {"语文":75,"数学":82,"英语":92} # 新增字典元素
print(dict3)
dict3["小明"]["语文"] = 68 # 更新字典元素
print(dict3)
# 删除元素,并返回一个value,如果这个value是字典,那么他也可以根据key继续获取对应的value
dict_cache = dict3.pop("小李")
print(f"删除后原来的字典: {dict3} ,\n获取的value是: {type(dict_cache)} 类型,他的语文分数是: {dict_cache["语文"]}")
print(f"这个字典中的key是:{dict3.keys()} , 类型是: {type(dict3.keys())} ") # 获取字典中全部的key
print(f"统计字典内,有 {len(dict3)} 个元素") # 统计字典内,有多少元素
# 通过for循环取出嵌套字典的值,这里举例可以取出所有的分数的value 方法1
for i in dict3.keys():
for j in dict3.keys():
print(dict3[j])
# 通过for循环取出嵌套字典的值,这里举例可以取出所有的分数的value 方法2
for ii in dict3:
for jj in dict3[ii]:
print(f"第二种for循环字典的方式{dict3[ii][jj]}")
dict3.clear() # 清空字典
# 字典练习:
dict_work1 = {
"小红":{"部门":"科技部","工资":3000,"级别":1},
"小明":{"部门":"市场部","工资":5000,"级别":2},
"小芳":{"部门":"市场部","工资":7000,"级别":3},
"小李":{"部门":"科技部","工资":4000,"级别":1},
"小鹏":{"部门":"市场部","工资":6000,"级别":2}
}
for dict_al in dict_work1:
for dict_al_nc in dict_work1[dict_al]:
if dict_al_nc=="级别":
print(f"员工:{dict_al},现在的级别是:{dict_work1[dict_al][dict_al_nc]}")
if dict_work1[dict_al][dict_al_nc] == 1:
dict_work1[dict_al][dict_al_nc] = 2
dict_work1[dict_al]["工资"] = dict_work1[dict_al]["工资"] + 1000
print(f"恭喜员工:{dict_al},你升职加薪了,现在的级别是:{dict_work1[dict_al][dict_al_nc]},薪水是:{dict_work1[dict_al]["工资"]}")
print(dict_work1)
"""
数据容器的通用操作 - 遍历
首先,在遍历上:
· 5类数据容器都支持for循环遍历
· 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)
统计容器的元素个数:
· len(容器)
统计容器的最大元素--注意,仅支持同类型的对比!!
· max(容器)
统计容器的最小元素--注意,仅支持同类型的对比!!
· min(容器)
除了下标索引这个共性外,还可以通用类型转换
将给定容器转换为列表:
· list(容器)
将给定容器转换为字符串:
· str(容器)
将给定容器转换为元组:
· tuple(容器)
将给定容器转换为集合:
· set(容器)
排序功能:
语法:sorted(容器,[reverse=True])
功能:将给定的容器进行排序。
注意:排序会返回列表类型!!
"""
list8=[1,2,3,4,5,6]
# 统计容器的最大和最小元素
print(f"list8的最大元素是:{max(list8)},最小元素是:{min(list8)}")
# 将给定容器转换为元组
print(tuple(list8))
# 将给定容器转换为集合:
print(set(list8))
# 将给定容器转换为字符串:
print(str(list8))
# 将字典转换为列表:注意:字典除了转字符串,转其他类型都只会保留key!
print(list(dict_work1))
# 将字典转换为字符串:注意:字典转字符串可以保留key和value!
print(str(dict_work1))
print("-------------排序功能----------")
# 排序功能
list8=[4,2,1,3,6,5]
print(sorted(list8))
tuple8=(4,2,1,3,6,5)
print(sorted(tuple8))
str9="ksjdjsa"
print(sorted(str9))
set={4,2,1,3,6,5}
print(sorted(set))
# 可以注意,排序只保留了key,还帮key顺便排序了
dict4={"key2":2,"key4":4,"key1":1,"key3":3,"key5":5,"key6":6}
print(sorted(dict4))
print("-------------反转排序功能----------")
# 反转排序功能
list8=[4,2,1,3,6,5]
print(sorted(list8,reverse=True))
tuple8=(4,2,1,3,6,5)
print(sorted(tuple8,reverse=True))
str9="ksjdjsa"
print(sorted(str9,reverse=True))
set6={4,2,1,3,6,5}
print(sorted(set6,reverse=True))
dict4={"key2":2,"key4":4,"key1":1,"key3":3,"key5":5,"key6":6}
print(sorted(dict4,reverse=True))
"""
数据容器总结:
数据容器可以从以下视角进行简单的分类:
· 是否支持下标索引:
· 支持:列表、元组、字符串 - 序列类型
· 不支持:集合、字典 -非序列类型
· 是否支持重复元素:
· 支持:列表、元组、字符串 - 序列类型
· 不支持:集合、字典 - 非序列类型
· 是否可以修改:
· 支持:列表、集合、字典
· 不支持:元组、字符串
基于各类数据容器的特点,它们的应用场景如下:
· 列表:一批数据,可修改、可重复的存储场景。
· 元组:一批数据,不可修改、可重复的存储场景。
· 字符串:一串字符串的存储场景。
· 集合:一批数据,去重存储场景。
· 字典:一批数据,可用key检索value的存储场景。
拓展:字符串的大小
在程序中,字符串所用的所有字符如:
· 大小写英文单词
· 数字
· 特殊符号(!、@、#、空格等)
都有其对应的ASCII码表值
每一个字符都等对应上一个:数字的码值
字符串进行比较就是基于数字的码值大小进行比较的。
字符串比较是按位比较,也就是一位位进行对比,只要有一位大,那么整体就大。
"""
|