数据容器:一种可容纳多份数据的数据类型(容器),容纳的每一份数据称之为1个元素,每一个元素都可以是任意类型的数据,如字符串、数字、布尔
列表(list) 字符串(str) 元组(tuple) 集合(set) 字典(dict)
列表(list)
定义:列表名称 = [元素1,元素2,元素3,...]
特点:可存储不同类型的元素
元素有序、可重复、元素可以修改
注:从前向后(正向索引),下标从0开始
从后向前(反向索引),下标从-1开始
列表元素的查看、删除、修改
查看:list1[0] 修改:list1[0]="A" 删除:del list1[3]
**注:**如果指定的索引值超出范围,将会报错
列表的切片:
指对操作的数据截取其中一部分的操作
语法:s[start:end:step]
特点:start:开始索引,不指定默认为0(第一个元素的索引)
end:结束索引,不指定默认为列表长度(直到列表末尾)
step:步长,不指定默认为1
s = ["A","B","C","D","E","F","G","H","I","J"]
#切片操作
print(s[0:5:1]) #['A', 'B', 'C', 'D', 'E']
print(type(s[0:5:1])) #<class 'list'>
print(s[:5:]) #['A', 'B', 'C', 'D', 'E']
print(s[:5:]) #['A', 'B', 'C', 'D', 'E']
print(s[:5]) #['A', 'B', 'C', 'D', 'E']
print(s[:5:2]) #['A', 'C', 'E']
print(s[:-2:1]) #['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
列表的常见方法:
|----------------|-------------------------------------|-------------------|
| 方法 | 作用 | 样例 |
| append( ) | 在列表的尾部追加元素 | s.append(10086) |
| insert( ) | 在指定索引之前,插入该元素 | s.insert(0,92) |
| remove( ) | 移除 列表中第一个匹配到的值 | s.remove(75) |
| pop( ) | 删除列表中指定索引位置的元素(如果未指定索引,默认删最后一个) | s.pop(2)/s.pop( ) |
| sort( ) | 对列表进行排序(列表元素的数据类型一致,才可以进行排序) | s.sort( ) |
| reverse( ) | 反转列表元素 | s.reverse( ) |
例1:将用户输入的10个数字,存储到一个列表中,并将列表中的数字进行排序,输出其中的最小值、最大值和平均值
num_list = [] #定义空列表
for i in range(10): #将用户输入的10个数存入列表
num = int(input("请输入一个整数:"))
num_list.append(num)
print("输出数字列表:",num_list)
num_list.sort() #用sort()时,必须先单独执行排序,再打印原列表(因为它返回None,不能直接放print 里)
print("排序后",num_list)
print(num_list[0],num_list[-1]) #最小min()、最大值max()
print(sum(num_list)/len(num_list))
写法 1:先排序,再打印( 直接把 num_list 本身改成有序的,但这个方法的返回值是 None)
写法 2:用 sorted()( 返回一个新的有序列表,不修改原列表 ),可直接在 print 里用
print("排序后",sorted(num_list))
例:合并两个列表中的元素,并对合并的结果进行去重处理(去重列表中的重复元素)
法一:
num_list1 = [19,23,54,64,875,20,109,232,123,54]
num_list2 = [55,80,72,35,60,123,54,29,91]
#合并列表
for num in num_list2:
num_list1.append(num)
print("合并后的原始列表",num_list1)
new_list = [] #去重记录的列表
for num in num_list1:
if num not in new_list: #不存在则添加
new_list.append(num)
print(new_list)
法二:(简化)
num_list1 = [19,23,54,64,875,20,109,232,123,54]
num_list2 = [55,80,72,35,60,123,54,29,91]
#合并列表
num_list = num_list1 + num_list2
print("合并后的原始列表",num_list)
new_list = []
for num in num_list:
if num not in new_list: #不存在则添加
new_list.append(num)
print(new_list)
法三:
num_list1 = [19,23,54,64,875,20,109,232,123,54]
num_list2 = [55,80,72,35,60,123,54,29,91]
#合并列表 ↓解包:将列表这一类容器解开成一个一个独立的元素 组包:将多个值合并到一个容器
num_list = [*num_list1,*num_list2]
print("合并后的原始列表",num_list)
new_list = []
for num in num_list:
if num not in new_list: #不存在则添加
new_list.append(num)
print(new_list)
、例:生成1-20的平方列表 -->range(1,21)
法一:(传统方式)
num_list = []
for i in range(1,21):
num_list.append(i ** 2)
print(num_list)
法二:(列表推导式)-->语法格式:[i**2 for i in 序列/列表]
num_list = [i**2 for i in range(1, 21)] #
print(num_list)
列表推导式:按照一定的规则快速生成一个列表的方法
格式1:列表名称= [ 要插入列表的数据 for i in 列表 ]
格式2:列表名称= [ 要插入列表的数据 for i in 列表 if 条件 ]
list1 = [11, 2, 31, 4, -5, 15, 17, 28, 49, 10, -11, 16, 54, -14, 36, -16, 87, -39]
print([x for x in list1 if x > 0])
字符串(str)
字符串是字符的容器,一个字符串可存放任意数量的字符。如:"Python" 'Python' """Python"""
特点:不可变性(无法修改)、有序性、可迭代性(能用for循环遍历)
注:从前向后(正向索引),下标从0开始
从后向前(反向索引),下标从-1开始
字符串切片:
语法:s[start:end:step]
s = "python-ai" #都输出ai
print(s[7:])
print(s[7::1])
print(s[7:9:1])
print(s[0:6:-1]) #截取不出来,因为从前往后,又从后往前
print(s[-1:-3:-1]) #ia
print(s[::-1]) #反转 ia-nohtyp
字符串的常见方法:
|--------------------|-----------------------------------------|--------------------------|
| 方法 | 作用 | 样例 |
| find( ) | 在字符串中查找子串,返回第一次出现的索引位置 ,找不到返回-1 | s.find('Python') |
| count( ) | 统计子串在字符串中出现的次数 | s.count('H') |
| upper( ) | 将字符串中的所有字母转换为大写 | s.upper( ) |
| lower( ) | 将字符串中的所有字母转换为小写 | s.lower( ) |
| split( ) | 将字符串按指定分隔符分割成 列表 | s.split(' ') |
| strip( ) | 去除 字符串两端的空白字符 或指定字符 | s.strip( )/s.strip('*') |
| replace( ) | 将字符串中的指定子串替换为新的子串 | s.replace('H','C') |
| startswitch( ) | 检查字符串是否以指定子串开头 ,返回布尔值 | s.startswith('p') |
| endswith( ) | 检查字符串是否以指定子串结尾 ,返回布尔值 | s.endswith('P') |
例:邮箱格式验证,验证是否正确(包含一个@和至少一个.)
xiaoyu@163.com xiaoyu@mail.new.cn
法一:
mail = input("请输入邮箱:")
if mail.count("@") and mail.count(".") >= 1:
print(f"{mail}是合法的邮箱")
else:
print(f"{mail}是不合法的邮箱")
法二:
mail = input("请输入邮箱:")
if mail.count("@") and '.' in mail:
print(f"{mail}是合法的邮箱")
else:
print(f"{mail}是不合法的邮箱")
例:判断字符串是否为回文字符串
法一:
s1 = "黄山落叶松叶落山黄"
reversed_s1 = s1[::-1]
if s1 == reversed_s1:
print(f"{s1}是回文字符串")
法二:
s1 = "黄山落叶松叶落山黄"
long = len(s1) # 第一步:获取字符串长度(基础操作)
flag = True # 标记是否是回文
for i in range(long // 2):
left = s1[i]
#左边第 i 位 ↔ 右边倒数第 i+1 位
right = s1[-(i+1)]
if left != right:
flag = False
break
if flag:
print(f"{s1}是回文字符")
else:
print(f"{s1}不是回文字符")
元组(tuple)
特点:可存储不同类型的元素,元素可重复、有序、不可修改(支持索引访问、切片)
定义元组:元组名称 = (元素1,元素2,...)
定义空元组:元组名称 = ( )
元组名称 = tuple( )
元组的常见方法:
(因为不可修改,所以只有查询方法) 仅有的 2 个内置方法
|--------------|---------------------------|--------------|
| 方法 | 作用 | 样例 |
| count( ) | 统计某元素在元组中出现的次数 | t1.count(80) |
| index( ) | 查找某个元素在元组中的索引位置(第一次出现的位置) | t1.index(80) |
注: 如果定义单元素的元组时,需在结尾加上逗号 ,例('A',),不然会被当成提高优先级的小圆括号
元组的组包与解包:
组包(Packing):将多个值合并到一个容器(元组、列表)中
解包(Unpacking):将容器(元组、列表)解开成独立的元素,分别赋值给多个变量
#定义元组,组包
t1 = (5,7,9,2,3,5)
t2 = 5,7,9,2,3,5
print(type(t2)) #<class 'tuple'>
#基础解包
a,b,c,d,e,f = t1 #变量数量与容器的元素个数一致
print(a,b,c,d,e,f) #5 7 9 2 3 5
#(*)扩展解包
x,*y,z = t1 #print(x,y,z) 5 [7, 9, 2, 3] 5
s,*o = t1 #print(s,o) 5 [7, 9, 2, 3, 5]
*o,e = t1 #print(o,e) [5, 7, 9, 2, 3] 5
注:在元组解包时,*表示收集剩余的所有元素 ,允许我们处理不确定数量的元素(生成列表,以便于可以进行进一步的处理)
例:根据学生成绩单,完成以下操作
1、计算每个学生的总分,各科平均分,然后一并输出
2、统计各科成绩的最低分、最高分、平均分并输出
3、查找成绩优秀(平均分大于90)的学生并输出
students = (
("s001","王林",85,92,78),
("S002", "李梦", 92, 88, 95),
("S003", "肖三", 78, 85, 82),
("S004", "牛十八", 89, 79, 91),
("S005", "周默", 95, 86, 89),
("S006", "王卓", 76, 82, 77),
("S007", "红绫", 89, 91, 94),
("S008", "佟立恒", 75, 89, 82),
("S009", "乔木", 86, 89, 98),
("S010", "潘天", 66, 59, 72)
)
# 1、计算每个学生的总分,各科平均分,然后一并输出 {avg:.1f}-->avg保留一位小数
print("学号\t\t姓名\t\t语文\t\t数学\t\t英语\t\t总分\t\t\t平均分")
#法一:
for s in students:
total = s[2]+s[3]+s[4]
avg = total/3
print(f"{s[0]} \t {s[1]} \t {s[2]} \t {s[3]} \t {s[4]} \t {total} \t {avg:.1f}")
#法二:元组解包
for id,name,chinese,math,english in students:
total = chinese+math+english
avg = total/3
print(f"{id} \t {name} \t {chinese} \t {math} \t {english} \t {total} \t {avg:.1f}")
# 2、统计各科成绩的最低分、最高分、平均分并输出
chinese_score = [s[2] for s in students]
math_score = [s[3] for s in students]
english_score = [s[4] for s in students]
print("语文成绩为:",chinese_score)
print(f"语文最低分{min(chinese_score)},最高分{max(chinese_score)},平均分{sum(chinese_score)/len(chinese_score)}")
print(f"数学最低分{min(math_score)},最高分{max(math_score)},平均分{sum(math_score)/len(math_score)}")
print(f"英语最低分{min(english_score)},最高分{max(english_score)},平均分{sum(english_score)/len(english_score)}")
# 3、查找成绩优秀(平均分大于90)的学生并输出
for s in students:
total = s[2]+s[3]+s[4]
avg = total/3
if avg >= 90:
print(f"{s[0]} \t {s[1]} \t {s[2]} \t {s[3]} \t {s[4]} \t {total} \t {avg:.1f}")
集合(set)
用于批量存储唯一的数据(身份证、手机号)
特点:无序的、不可重复的、可修改的数据容器
定义集合:s1={"c","d","x"}
定义空集合:s1=set( )
注: 空集合 的定义不可以使用{ } ,{ }表示的是空字典 ,由于集合是无序的,因此不支持下标索引访问
集合的常见方法:
|---------------------|---------------------------------------------|---------------------|
| 方法 | 作用 | 样例 |
| add(..) | 添加元素到集合中 | s1.add('t') |
| remove(..) | 移除 集合中的指定元素(指定元素不存在将报错) | s1.remove('t') |
| pop( ) | 随机删除 集合中的元素并返回 | e=s1.pop() |
| clear( ) | 清空集合 | s1.clear( ) |
| difference( ) | 求取两集合的差集 ( 包含在第一个集合但不包含在第二个集合)- | s1.difference(s2) |
| union( ) | 求取两个集合的并集 | | s1.union(s2) |
| intersection( ) | 求取两个集合的交集 & | s1.intersection(s2) |
s1 = {"A","B","C","D","E","X","Y"}
s2 = {"C","E","Y","Z"}
print(s2.difference(s1)) #{'Z'}
#随机删除
e = s1.pop()
print(e) #E
print(s1) #{'D', 'Y', 'X', 'B', 'C', 'A'}
#去除重复
s1 = {"A","B","C","D","E","X","Y","Y","A","B","C","D"}
football_set = {"王林", "曾牛", "徐立国", "通天", "天运子", "韩立", "厉飞雨", "乌丑", "紫灵"}
basketball_set = {"张铁", "墨居仁", "王林", "姜老道", "曾牛", "王蝉", "韩立", "天运子", "李化元", "厉飞雨", "云麓"}
french_set = {"许木", "王卓", "十三", "虎咆", "姜老道", "天运子", "红蝶", "厉飞雨", "韩立", "曾牛"}
art_set = {"通天", "天运子", "韩立", "虎咆", "姜老道", "紫灵"}
#1、找出同时选择法国和艺术的学生-->交集
法一:
fa_set1 = french_set.intersection(art_set)
print(fa_set1)
法二:
fa_set2 = french_set & art_set
print(fa_set2)
#2、找出选择了足球,但是没有选择篮球的学生-->差集
法一:
fb_set1 = football_set.difference(basketball_set)
print(fb_set1)
法二:
fb_set2 = football_set - basketball_set
print(fb_set2)
法三:集合推导式-->快速构建集合,语法:{要往集合中添加的数据 for s in set1 if 条件}
fb_set3 = {s for s in football_set if s not in basketball_set}
print(fb_set3)
#3、统计每一个学生选修的课程数量
#3.1、获取到学生名单
法一:
all_set1 = football_set.union(basketball_set).union(french_set).union(art_set)
print(all_set1)
法二:
all_set2 = football_set | basketball_set | french_set | art_set
print(all_set2)
all_list = [*football_set, *basketball_set, *french_set, *art_set] #set会去重,所以用list
for s in all_list:
print(f"{s}选择了{all_list.count(s)}课程")
字典(dict)
存储的是键值对(key: value)类型的数据,可根据键(key)找到对应的值(value)
特点:键值对(key: value)存储、键(key)不能重复、可修改
定义字典:字典名称={key:value,key:value,...}
定义空字典:字典名称 = { }
字典名称 = dict( )
根据key获取value
值 = 字典名称[key]
注: 字典内的key不允许重复,如果重复定义,后面会覆盖前面的
value可以是任意类型,而key必须是不可变类型(str、int、float、tuple),不能是list、set、dict
字典是没有索引下标 的,不能根据索引获取值,只 可以根据key获取value
字典的增删改查操作方式:
|--------|--------------------|------------------------------------------------|-----------------------|
| 类型 | 操作 | 含义 | 样例 |
| 添加 | 字典名称[key]=value | 往指定字典 中添加 key-value键值对 | dict1["小雨"]=688 |
| 删除 | 字典名称.pop(key) | 删除 字典中指定的key ,并返回 该key对应的value | score=dict1.pop("小雨") |
| 删除 | del 字典名称[key] | 删除 字典中指定的键值对 | del dict1["小雨"] |
| 修改 | 字典名称[key]=value | 修改 字典中指定的key对应的值 | dict1["小智"]=657 |
| 查询 | 字典名称[key] | 根据key获取value | dict1["小智"] |
| 查询 | 字典名称**.get(key)** | 根据key获取value | dict1.get("小智") |
| 查询 | 字典名称**.keys( )** | 获取所有的key | dict1.keys( ) |
| 查询 | 字典名称**.values( )** | 获取所有的value | dict1.values( ) |
| 查询 | 字典名称**.items( )** | 获取所有的key-value键值对 | dict1.items( ) |
dict1 = {"小智":675,"李思":608,"李琦":453,"小黑":423}
print(dict1)
#添加
dict1["小雨"] = 666
print(dict1)
#修改
dict1["小雨"] = 750
print(dict1)
#查询
print(dict1["李思"]) #608
print(dict1.get("李思")) #608
#获取所有key值
print(dict1.keys()) #dict_keys(['小智', '李思', '李琦', '小黑', '小雨'])
#获取所有value值
print(dict1.values()) #dict_values([675, 608, 453, 423, 750])
#获取所有键值对
print(dict1.items()) #dict_items([('小智', 675), ('李思', 608), ('李琦', 453), ('小黑', 423), ('小雨', 750)])
#删除
score = dict1.pop("小智")
print(score)
print(dict1) #{'李思': 608, '李琦': 453, '小黑': 423, '小雨': 750}
del dict1["小雨"]
print(dict1) #{'李思': 608, '李琦': 453, '小黑': 423}
遍历
for k in dict1.keys():
print(f"{k} : {dict1[k]}")
for item in dict1.items():
print(f"{item[0]} : {item[1]}")
for k,v in dict1.items(): #解包
print(f"{k} : {v}")
#输出
李思 : 608
李琦 : 453
小黑 : 423
例:开发一个购物车管理系统,实现商品信息的添加、修改、删除、查询功能。系统使用字典结构存储商品数据。
1、添加购物车:用户根据提示录入商品名称、以及该商品的价格、数量、保存该商品信息到购物车
2、修改购物车:要求用户输入要修改的购物车商品名称,然后再提示输入该商品的价格、数量,输入完成后修改该商品信息
3、删除购物车:要求用户输入要删除的购物车名称,根据名称删除购物车中的商品
4、查询购物车:将购物车的商品信息展示出来,格式为:"商品名称:xxx,商品价格:xxx,商品数量:xxx"
5、退出购物车
#购物车列表数据
例:↓shopping_cart = {"Meta80":{"price":6999,"num":2},"鼠标":{...}}
shopping_cart = {}
#制作菜单
print("欢迎使用购物车管理系统:~")
menu = """
####### 购物车系统 ########
# 1.添加购物车 #
# 2.修改购物车 #
# 3.删除购物车 #
# 4.查询购物车 #
# 5.退出购物车 #
#########################
"""
while True:
print(menu)
# 执行的具体操作
choice = input("请选择要执行的操作(1-5):")
match choice:
case "1":#添加购物车
goods_name = input("请输入商品名称:")
goods_price = float(input("请输入商品价格:"))
goods_num = int(input("请输入商品数量:"))
if goods_name in shopping_cart:
print("该商品已存在,请重新选择~")
else:
shopping_cart[goods_name] = {"price":goods_price,"num":goods_num}
print("商品添加完毕~")
case "2":#修改购物车 添加和修改的代码一样
goods_name = input("请输入要修改的商品名称:")
if goods_name not in shopping_cart:
print("该商品不存在,请重新选择~")
continue
goods_price = float(input("请输入最新的商品价格:"))
goods_num = int(input("请输入商品最新的数量:"))
shopping_cart[goods_name] = {"price":goods_price,"num":goods_num}
print("商品修改完毕~")
case "3":#删除购物车
goods_name = input("请输入要删除的商品名称:")
if goods_name not in shopping_cart:
print("该商品不存在,请重新选择~")
else:
del shopping_cart[goods_name]
print("商品删除成功~")
case "4":#查询购物车
for goods_name in shopping_cart.keys():
goods_info = shopping_cart.get(goods_name) #或shopping_cart[goods_name]
print(f"商品名称:{goods_name},商品价格:{goods_info['price']},商品数量:{goods_info['num']}")
case "5":#退出购物车
print("Bye")
break
case _:
print("非法操作,不支持!!!!")