本文为「30天吃透Python核心语法」系列第十篇,承接Day9的列表内容,全程纯文字讲解、零基础友好、无晦涩术语,每一个知识点都配可直接运行的代码示例,彻底搞定Python结构化数据存储的核心工具。
大家好,欢迎来到30天Python精通计划的第十天。
Day9我们一起搞定了Python最常用的列表容器,终于解决了批量数据存储的问题,不用再为一组数据定义十几个变量,很多同学都用列表写出了成绩统计、购物清单管理的小脚本,进步非常快!
但这段时间我也收到了很多新手同学的留言:
- 有些固定数据比如身份证号、出生日期,我不想让代码不小心修改它,列表能随便改,太不安全了,有没有不能修改的容器?
- 用列表存用户信息,要记年龄在索引2、城市在索引3,太麻烦了,能不能直接用“年龄”“城市”当名字找对应的数据?
- 我要存商品的详情,有名称、价格、库存、产地,用列表存根本分不清哪个数据对应什么含义,有没有更直观的存储方式?
别慌,这些问题的答案,就是今天我们要学的元组(Tuple)和字典(Dict)。
如果说列表是「可随时调整的多层收纳柜」,那元组就是「封死的固定收纳盒」,一旦装好就不能修改,完美保护固定数据;而字典就是「带标签的收纳柜」,每个数据都有专属的名字标签,不用记编号,直接通过标签就能精准找到对应的数据,是Python中处理结构化数据的绝对核心。
这两个容器和列表一起,构成了Python最常用的三大基础数据容器,学完今天的内容,不管是固定数据保护,还是复杂的用户、商品信息存储,你都能找到最合适的解决方案,为后续办公自动化、数据分析、接口开发打下核心基础。
学完今天的内容,你将:
✅ 彻底搞懂元组的核心特性,学会元组的定义与基础操作
✅ 分清元组和列表的核心区别,精准选择适用场景
✅ 吃透字典的键值对结构,掌握字典增删改查四大核心操作
✅ 学会字典的4种遍历方式,轻松处理结构化数据
✅ 掌握元组和字典的高频内置方法,避开新手90%的报错
✅ 理清列表、元组、字典三大容器的适用场景,选对工具效率翻倍
一、第一部分:元组(Tuple)—— 不可变的安全数据容器
1. 先搞懂:什么是元组?
用一句大白话讲,元组是Python中专门用来存储固定数据的不可变有序容器。
它和列表的核心功能几乎完全一致,唯一的、也是最本质的区别就是:列表是可变的,创建后可以随时增删改里面的元素;元组是不可变的,创建完成后,里面的元素不能修改、不能添加、不能删除。
我们拆解元组的核心特点,新手一眼就能懂:
1. 不可变性:这是元组的灵魂,一旦定义完成,就不能修改里面的任何元素,也不能新增和删除,从根源上避免数据被误改;
2. 有序性:和列表一样,元组里的每个元素都有固定的索引,支持索引取值和切片操作,规则和列表、字符串完全一致;
3. 兼容性:和列表一样,元组里可以同时存储整数、字符串、布尔值,甚至嵌套列表、元组等任意类型的数据;
4. 可迭代性:可以用for循环直接遍历元组里的每一个元素,用法和列表完全一致。
2. 元组的基础定义语法
元组的定义用英文小括号 () 包裹,里面的元素之间用英文逗号分隔,语法和列表高度相似,新手可以直接联动记忆。
这里重点提醒:逗号是元组的核心标志,不是小括号,哪怕没有小括号,只要有逗号,Python也会识别为元组,这是新手最容易踩的坑。
下面我们用几个示例,带你掌握元组的4种常见定义方式,代码可以直接复制运行:
python
# 1. 定义空元组
empty_tuple = ()
print(empty_tuple)
print(type(empty_tuple))
# 2. 定义单元素元组【新手红线!必须加末尾的逗号】
# 正确写法:单元素必须加逗号,才会被识别为元组
single_tuple = (10,)
print(single_tuple)
print(type(single_tuple))
# 错误写法:没有逗号,会被识别为整数,不是元组
wrong_tuple = (10)
print(type(wrong_tuple)) # 输出int,不是tuple
# 3. 定义多元素元组(最常用)
# 存储一个人的固定信息:姓名、身份证号、出生日期
user_info = ("张三", "110101199001011234", "1990-01-01")
print(user_info)
# 4. 定义嵌套元组,元组里可以再放元组、列表
class_info = (("张三", 20, 85), ("李四", 21, 92), ("王五", 19, 78))
print(class_info)
# 5. 省略括号的写法,Python会自动识别为元组
auto_tuple = 10, 20, 30
print(auto_tuple)
print(type(auto_tuple))
3. 元组的核心操作
因为元组是不可变的,所以没有列表的增、删、改方法,只有查询、遍历、统计等不修改元组本身的操作,所有规则和列表完全一致,Day9学的知识点可以直接复用。
① 索引与切片取值
和列表完全一致,支持正向索引、反向索引、切片操作,核心规则还是左闭右开。
python
user_info = ("张三", "李四", "王五", "赵六")
# 正向索引取第一个元素
print(user_info[0])
# 反向索引取最后一个元素
print(user_info[-1])
# 切片取前3个元素
print(user_info[:3])
# 倒序元组
print(user_info[::-1])
【新手避坑提示】元组的索引越界同样会报错,取值前可以用 len(元组名) 查看元组的元素个数,避免越界。
② 元组的遍历
和列表完全一致,支持直接遍历元素,也支持用enumerate()带索引遍历。
python
# 直接遍历元素
fruit_tuple = ("苹果", "香蕉", "橙子", "葡萄")
for fruit in fruit_tuple:
print(f"水果:{fruit}")
# 带索引遍历
for index, fruit in enumerate(fruit_tuple):
print(f"第{index+1}个水果:{fruit}")
③ 元组的高频内置方法
因为不可变性,元组只有两个常用的内置方法,不会修改元组本身,只会返回统计结果:
1. count():统计指定元素在元组中出现的次数
2. index():查找指定元素第一次出现的索引位置,元素不存在会报错
python
score_tuple = (85, 92, 78, 90, 88, 78, 92)
# 统计78出现的次数
print(score_tuple.count(78))
# 查找92第一次出现的索引
print(score_tuple.index(92))
④ 元组的拼接与重复
元组虽然不能修改,但可以通过加号拼接两个元组、乘号重复元组,生成一个全新的元组,原有的元组不会被改变。
python
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
# 拼接两个元组,生成新元组
new_tuple = tuple1 + tuple2
print(new_tuple)
# 重复元组3次
repeat_tuple = tuple1 * 3
print(repeat_tuple)
# 原元组不会被改变
print(tuple1)
【新手红线提醒】绝对不能尝试修改元组里的元素,比如 tuple1[0] = 10 ,程序会直接报错,这是元组不可变性的核心体现。
4. 元组的适用场景
很多新手会问:元组不能修改,功能比列表少,为什么还要用它?
核心原因就是它的不可变性,在这些场景下,元组比列表更合适、更安全:
1. 存储固定不变的数据:比如身份证号、出生日期、省份编码、常量配置等,用元组存储,从根源上避免数据被误修改;
2. 函数返回多个值:Python函数返回多个值时,默认就是用元组封装的,这是Python最常用的元组场景;
3. 作为字典的键:字典的键必须是不可变类型,列表不能当键,而元组可以,适合用多维度信息当键的场景;
4. 保护数据安全:在多人协作开发时,把不需要修改的数据用元组存储,避免其他开发者不小心修改数据导致bug。
二、第二部分:字典(Dict)—— 带标签的结构化数据容器
如果说列表、元组是靠索引编号找数据,那字典就是靠「名字标签」找数据,是Python中处理结构化数据最常用、最高效的容器,没有之一。
日常开发中,用户信息、商品详情、接口返回数据、配置信息,几乎全都是用字典存储的,这部分是今天的重中之重,必须彻底吃透。
1. 先搞懂:什么是字典?
用一句大白话讲,字典是Python中用「键值对」存储数据的可变无序容器(Python3.7+保留插入顺序)。
什么是键值对?我们可以把它想象成身份证:键(key)就是身份证号,是唯一的、固定的;值(value)就是身份证上的个人信息,是和键绑定的、可以修改的。我们只要知道键(身份证号),就能精准找到对应的值(个人信息),不用像列表一样记索引编号,查找效率极高。
我们拆解字典的核心特点,新手必须记牢:
1. 键值对结构:字典里的每一个数据,都是由「键(key): 值(value)」组成的,键和值之间用英文冒号分隔,键值对之间用英文逗号分隔;
2. 键的唯一性:字典里的键必须是唯一的,不能重复,如果同一个键赋值多次,后面的值会直接覆盖前面的;
3. 键的不可变性:字典的键必须是不可变类型,比如字符串、数字、元组,绝对不能用列表、字典这种可变类型当键,会直接报错;而值可以是任意类型,没有任何限制;
4. 可变性:字典创建完成后,可以随时新增、修改、删除键值对,和列表一样灵活;
5. 高效查找:不管字典里有多少数据,通过键找值的速度都极快,不会因为数据变多而变慢,这是列表比不了的优势。
2. 字典的基础定义语法
字典的定义用**英文大括号 {} **包裹,里面的每一组数据都是 键: 值 的格式,键值对之间用英文逗号分隔。
下面我们用几个示例,带你掌握字典的3种常见定义方式,覆盖所有日常场景:
python
# 1. 定义空字典
empty_dict = {}
print(empty_dict)
print(type(empty_dict))
# 2. 常规字典定义(最常用)
# 存储一个用户的详细信息,键是信息名称,值是对应内容
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市",
"is_student": True,
"score": 85.5
}
print(user_dict)
# 3. 定义嵌套字典(最贴合实际场景)
# 存储用户的多层级信息,值可以是另一个字典、列表
student_dict = {
"name": "李四",
"age": 21,
"contact": {
"phone": "13800138000",
"email": "lisi@example.com"
},
"scores": [85, 92, 78, 90]
}
print(student_dict)
# 4. 重复键的情况:后面的值会覆盖前面的
repeat_dict = {"name": "张三", "name": "李四"}
print(repeat_dict) # 只会输出{'name': '李四'}
3. 字典的核心操作一:查(获取值)
字典最核心的操作就是通过键获取对应的值,Python给我们提供了两种常用的取值方式,分别适用于不同场景,下面我们逐个拆解,讲清优缺点和适用场景。
① 方括号直接取值:[键名]
这是最基础、最常用的取值方式,语法和列表的索引取值类似,只是把方括号里的索引换成了字典的键。
语法格式: 字典名[键名]
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 通过键获取对应的值
print(user_dict["name"])
print(user_dict["age"])
print(user_dict["city"])
# 嵌套字典取值:一层一层找键
student_dict = {
"name": "李四",
"contact": {"phone": "13800138000"}
}
# 先找contact键,再找里面的phone键
print(student_dict["contact"]["phone"])
【新手避坑红线】如果用这种方式取值,键在字典里不存在,程序会直接报KeyError错误,这是新手用字典时100%会踩的坑。
② get()方法取值(新手优先推荐)
这是更安全、更推荐的取值方式,核心优势是:如果键不存在,不会直接报错,而是返回None,或者你指定的默认值,完美避免程序崩溃。
语法格式: 字典名.get(要查找的键, 键不存在时返回的默认值) ,默认值是可选的,不写的话键不存在会返回None。
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 键存在时,和方括号取值结果一致
print(user_dict.get("name"))
# 键不存在时,返回None,不会报错
print(user_dict.get("gender"))
# 键不存在时,返回你指定的默认值
print(user_dict.get("gender", "未知"))
【新手建议】除非你100%确定键一定存在,否则优先用get()方法取值,尤其是处理用户输入、接口返回的不确定数据时,能极大减少程序报错。
4. 字典的核心操作二:增(新增键值对)
给字典新增键值对的语法超级简单,核心逻辑是:给一个不存在的键直接赋值,就会在字典里新增这个键值对。
语法格式: 字典名[新键名] = 对应的值
python
user_dict = {
"name": "张三",
"age": 20
}
# 新增键值对:gender,值为男
user_dict["gender"] = "男"
# 新增键值对:phone,值为13800138000
user_dict["phone"] = "13800138000"
print(user_dict)
除了单个新增,还可以用 update() 方法批量新增多个键值对,适合一次性添加多个数据的场景:
python
user_dict = {"name": "张三", "age": 20}
# 批量新增多个键值对
user_dict.update({
"city": "上海市",
"gender": "男",
"is_student": True
})
print(user_dict)
5. 字典的核心操作三:改(修改已有键的值)
修改字典里已有键的值,和新增键值对的语法完全一致,区别是:赋值的键是字典里已经存在的,就会覆盖原来的值,实现修改效果。
语法格式: 字典名[已存在的键名] = 新的值
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 修改age键的值,从20改成21
user_dict["age"] = 21
# 修改city键的值,从北京市改成上海市
user_dict["city"] = "上海市"
print(user_dict)
同样,也可以用 update() 方法批量修改多个已有键的值,用法和批量新增完全一致。
6. 字典的核心操作四:删(删除键值对)
Python给字典提供了3种常用的删除方式,分别适用于不同的删除场景,下面我们逐个拆解:
① del关键字:删除指定键值对,或直接删除整个字典
和列表里的del用法一致,根据键名删除指定的键值对,删除后键值对会彻底消失,没有返回值。
语法格式: del 字典名[要删除的键名]
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 删除city键对应的键值对
del user_dict["city"]
print(user_dict)
# 直接删除整个字典,删除后字典就不存在了
del user_dict
② pop()方法:删除指定键值对,并返回对应的值
和列表的pop()方法类似,删除指定键对应的键值对后,会把被删除的值作为返回值,我们可以用变量接收,后续继续使用。
语法格式: 字典名.pop(要删除的键名, 键不存在时的默认值)
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 删除age键,并用变量接收被删除的值
deleted_age = user_dict.pop("age")
print(f"被删除的年龄是:{deleted_age}")
print(user_dict)
【优势】pop()方法可以设置默认值,就算要删除的键不存在,也不会报错,比del更安全,新手优先推荐。
③ clear()方法:清空字典里的所有键值对
和列表的clear()方法一致,一次性清空字典里的所有内容,让字典变成空字典,字典本身还存在,不会被删除。
语法格式: 字典名.clear()
python
user_dict = {"name": "张三", "age": 20}
# 清空字典所有内容
user_dict.clear()
print(user_dict) # 输出空字典{}
7. 字典的遍历:for循环处理字典数据
字典是可迭代对象,我们可以用for循环遍历字典,实现批量数据处理,这是字典最常用的场景之一。Python给我们提供了4种常用的遍历方式,覆盖所有日常需求,下面我们逐个拆解:
① 遍历字典的所有键:keys()方法
keys()方法会返回字典里所有的键,我们可以用for循环遍历每一个键。
语法格式: for 键变量 in 字典名.keys():
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 遍历所有的键
for key in user_dict.keys():
print(f"键:{key}")
# 可以通过键获取对应的值
print(f"对应的值:{user_dict[key]}")
② 遍历字典的所有值:values()方法
values()方法会返回字典里所有的值,适合只需要处理值,不需要键的场景。
语法格式: for 值变量 in 字典名.values():
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 遍历所有的值
for value in user_dict.values():
print(f"值:{value}")
③ 同时遍历键和值:items()方法(最常用)
items()方法会同时返回字典里的每一组键和值,不用再通过键找值,是遍历字典最常用、最高效的方式,新手必须掌握。
语法格式: for 键变量, 值变量 in 字典名.items():
python
user_dict = {
"name": "张三",
"age": 20,
"city": "北京市"
}
# 同时遍历键和值
for key, value in user_dict.items():
print(f"{key}:{value}")
④ 嵌套字典的遍历
实际开发中我们经常会遇到嵌套字典,遍历的时候只需要嵌套for循环即可,一层一层遍历。
python
class_dict = {
"student1": {"name": "张三", "age": 20, "score": 85},
"student2": {"name": "李四", "age": 21, "score": 92},
"student3": {"name": "王五", "age": 19, "score": 78}
}
# 遍历外层字典
for student_id, student_info in class_dict.items():
print(f"\n{student_id}信息:")
# 遍历内层的学生信息字典
for key, value in student_info.items():
print(f" {key}:{value}")
三、三大容器核心区别与适用场景总结
到这里,我们已经学完了Python三大核心基础数据容器:列表、元组、字典,很多新手会分不清什么时候该用哪个,这里用大白话给大家总结清楚,一眼就能选对:
1. 列表(List):用[]包裹,有序、可变、靠索引取值。适合存储一组同类型、会动态变化的数据,比如成绩列表、购物清单、用户名列表,需要频繁增删改、按顺序遍历的场景。
2. 元组(Tuple):用()包裹,有序、不可变、靠索引取值。适合存储一组固定不变、不希望被修改的数据,比如个人身份证信息、常量配置、函数多返回值,需要保护数据不被误改的场景。
3. 字典(Dict):用{}包裹,键值对结构、可变、靠键取值。适合存储有明确对应关系的结构化数据,比如用户信息、商品详情、配置项,需要通过标签快速查找数据的场景。
四、新手高频踩坑避坑指南
这里整理了Day10学元组和字典时,新手100%会遇到的报错和逻辑问题,提前讲清原因和解决方法,帮你少走弯路。
1. 元组单元素定义忘加逗号,类型错误
很多新手定义单元素元组时,写成 (10) ,结果被Python识别为整数,不是元组。解决方法:单元素元组必须在末尾加逗号,正确写法是 (10,) ,逗号才是元组的核心标志。
2. 尝试修改元组元素,触发TypeError报错
元组是不可变类型,不能修改、新增、删除里面的元素,写 tuple[0] = 10 会直接报错。解决方法:如果需要修改数据,就用列表;如果必须用元组,可以通过拼接生成新的元组,原元组无法修改。
3. 字典用方括号取不存在的键,触发KeyError报错
这是新手最常见的报错,用 dict["不存在的键"] 取值,键不存在会直接崩溃。解决方法:优先用get()方法取值,设置默认值,比如 dict.get("key", "默认值") ,键不存在也不会报错。
4. 用可变类型当字典的键,触发TypeError报错
字典的键必须是不可变类型,用列表、字典当键会直接报错。解决方法:只能用字符串、数字、元组这种不可变类型当键,值可以是任意类型。
5. 字典的键重复,导致数据被覆盖
字典的键必须唯一,同一个键多次赋值,后面的值会覆盖前面的,新手很容易不小心写重复的键,导致数据丢失。解决方法:定义字典时,确保所有键都是唯一的,不要重复。
6. 遍历字典的时候修改字典,导致遍历异常
很多新手会在for循环遍历字典的时候,新增或删除键值对,导致遍历结果不符合预期,甚至报错。解决方法:遍历字典的副本,或者先把键转换成列表再遍历,避免遍历过程中字典的结构发生变化。
7. 混淆元组和列表的括号,导致类型错误
新手很容易把元组的()和列表的[]写混,比如用[]定义元组,用()定义列表,导致后续操作报错。解决方法:牢记列表用[]、元组用()、字典用{},定义的时候就选对容器。
五、今日课后作业(必做!只看不敲,永远学不会)
编程是一门实操技能,只有动手敲代码,才能真正把元组和字典的知识点吃透。今天的作业循序渐进,覆盖所有核心操作,全部完成才算真正掌握。
1. 基础必做:定义一个元组,存储你的姓名、身份证号、出生日期3个固定信息,完成以下操作:打印元组的第二个元素、用for循环遍历整个元组、统计元组的元素个数,每一步都打印结果。
2. 进阶练习:定义一个字典,存储你的个人信息,包含姓名、年龄、所在城市、爱好(用列表存储)、是否是学生5个键值对,完成以下操作:用get方法获取年龄并打印、新增一个键值对“身高”、修改所在城市的值、删除是否是学生的键值对、用for循环遍历整个字典,打印每一组键和值。
3. 挑战练习:定义一个嵌套字典,存储3个学生的信息,每个学生的信息包含姓名、年龄、3门科目的成绩,完成以下操作:遍历所有学生,打印每个学生的姓名和总成绩、找出总成绩最高的学生姓名、统计所有学生的平均分。
4. 习惯养成:给每一步操作都加上清晰的单行注释,变量名用规范的蛇形命名法,做到见名知意。
六、明日预告
Day11我们将学习Python四大基础容器的最后一个:集合(Set),同时对四大容器做完整的总结与对比。
我们会搞懂集合的去重特性、交并补运算,学会用一行代码完成列表去重,同时理清四大容器的所有区别与适用场景,帮你把前3天学的容器知识彻底融会贯通,形成完整的知识体系。
结尾互动
今天的元组和字典,你都学会了吗?
是不是终于解决了结构化数据存储的痛点,不用再靠记索引找数据了?
完成作业的同学,可以在评论区扣个【打卡Day10】!
遇到任何报错、知识点搞不懂的问题,都可以在评论区留言,我会一一解答。
关注我,跟着30天计划,从零开始,彻底精通Python核心语法,每天1.5小时,30天就能独立写Python脚本,搞定日常办公自动化!