系列文章
Python 从入门到精通
第 4 / 36 篇
从环境安装和基础语法出发,逐步学习工程实践、自动化、数据处理与 Web 开发。
-
01
Python 怎么装、怎么用 -
02
变量、数字和字符串 -
03
列表:把一组数据放在一起 -
04
元组、集合和字典正在阅读 -
05
条件判断:让程序做选择 -
06
循环:重复的事交给程序 -
07
函数:把代码整理成可复用的块 -
08
模块与包:拆分你的程序 -
09
输入、输出与字符串格式化 -
10
文件读写:保存程序的数据 -
11
异常处理:程序出错时怎么办 -
12
基础阶段练习:命令行记账本 -
13
类和对象:面向对象入门 -
14
继承、组合与特殊方法 -
15
迭代器与生成器 -
16
列表推导式与生成器表达式 -
17
装饰器:给函数增加能力 -
18
上下文管理器与 with -
19
类型标注与 dataclass -
20
正则表达式:从文本中找规律 -
21
日期、时间与时区 -
22
日志与调试 -
23
虚拟环境与依赖管理 -
24
测试:让修改不再提心吊胆 -
25
网络请求:用 Python 调用 API -
26
网页解析与合规采集 -
27
操作 Excel、CSV 与批量文件 -
28
SQLite:给程序加一个数据库 -
29
数据分析入门:NumPy 与 Pandas -
30
画图:把数据变得直观 -
31
Flask 入门:做一个小网站 -
32
异步编程:同时处理多项任务 -
33
线程、进程与并发选择 -
34
性能分析与优化 -
35
项目结构、配置与发布 -
36
综合项目:从需求到上线
上一篇学了列表——一组数据排着队。但 Python 里装数据的容器不止它一个,还有三个常用兄弟:元组(tuple)、集合(set)和字典(dict)。这篇把它们一次讲清楚,顺便说说什么时候该用谁。
元组:不可变的列表
元组用圆括号 (),长得像列表,但有个关键区别:创建之后不能改。
point = (3, 5) # 坐标,用元组很合适
rgb = (255, 128, 0) # 颜色
print(point[0]) # 3(支持索引和切片,和列表一样)
print(point[1:]) # (5,)
# point[0] = 10 # 报错!TypeError: 'tuple' object does not support item assignment
元组不可变,但有个细节:不可变的是”元素引用”本身。如果元组里装的是列表这类可变对象,列表内部还是能改的。
两个语法细节:
a = (1) # 这是整数 1,不是元组!
b = (1,) # 加个逗号才是单元素元组
c = 1, 2, 3 # 不加括号也是元组(这叫打包)
x, y, z = c # 解包:把元组拆开赋值
print(x, y) # 1 2
解包是 Python 里很爽的写法,交换两个变量不用中间变量:
a, b = b, a # 一行交换
集合:去重和集合运算
集合用花括号 {},特点:元素唯一、无序(打印顺序不保证,要稳定顺序用 sorted)。最适合干两件事:去重、做交并差。
nums = [1, 2, 2, 3, 3, 3, 4]
unique = set(nums)
print(unique) # {1, 2, 3, 4}(重复的没了)
print(len(unique)) # 4
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b) # {3, 4} 交集
print(a | b) # {1, 2, 3, 4, 5, 6} 并集
print(a - b) # {1, 2} 差集(a 有 b 没有)
print(a ^ b) # {1, 2, 5, 6} 对称差(只在一个集合里的)
注意:{} 是空字典,空集合要用 set()。集合里的元素必须是可哈希的(数字、字符串、元组可以,列表不行)。
字典:键值对
字典是 Python 里最重要的数据结构,没有之一。它存的是键值对(key-value),像查字典一样用键找值:
student = {
"name": "小明",
"age": 18,
"city": "敦化",
}
print(student["name"]) # 小明
student["age"] = 19 # 改值
student["score"] = 92 # 加新键
print(student)
增删改查:
# 查:不存在的键直接报 KeyError
# print(student["phone"]) # KeyError: 'phone'
print(student.get("phone", "没留")) # 没留(get 带默认值,安全)
# 删
del student["city"]
# 遍历
for key in student: # 遍历键
print(key)
for key, value in student.items(): # 同时遍历键值
print(f"{key}: {value}")
for value in student.values(): # 只遍历值
print(value)
# 判断键是否存在
print("name" in student) # True
检查键在不在,用 in 比直接取更安全;get 带默认值也常用。
字典的嵌套
字典里套字典、套列表非常常见,比如一个班的学生:
class_ = {
"小明": {"age": 18, "scores": [92, 88]},
"小红": {"age": 17, "scores": [85, 95]},
}
print(class_["小明"]["scores"][0]) # 92
for name, info in class_.items():
avg = sum(info["scores"]) / len(info["scores"])
print(f"{name} 平均分 {avg:.1f}")
什么时候用哪个
- 列表:有序、要改、按位置取 → 学生的名单、待办事项
- 元组:有序、不改、内容固定 → 坐标、颜色、函数返回多值
- 集合:去重、判断在不在、交并差 → 统计不重复访客、对比两份名单
- 字典:按键找值、描述属性 → 学生信息、配置项、计数器
一句话记忆:元组是锁死的列表,集合是去重的袋子,字典是查表。
新手坑
坑 1:{} 不是空集合。它是空字典。空集合写 set()。
坑 2:字典键重复了。后面的覆盖前面的,不报错:
d = {"a": 1, "a": 2}
print(d) # {'a': 2}
坑 3:遍历字典时不能改字典大小。会报 RuntimeError: dictionary changed size during iteration。要删就遍历副本 for k in list(d):。
小结
- 元组
()不可变,支持索引切片和解包;单元素要加逗号 - 集合
set()去重、无序,支持&|-^运算 - 字典
{}键值对,d[key]取值、get()安全取值、items()遍历 - 选型:要改用列表,锁死用元组,去重用集合,查表用字典
练习
- 把字符串
"hello world hello python"拆成单词,统计每个单词出现几次(提示:split + 字典计数) - 有两个列表
a = [1, 2, 3, 4]和b = [3, 4, 5, 6],找出同时在两个列表里的数字(提示:集合交集) - 思考:为什么元组能当字典的键,列表不能?提示:想想字典是靠什么找到值的,列表能不能保证这一点?