系列文章

Python 从入门到精通

第 4 / 36 篇

从环境安装和基础语法出发,逐步学习工程实践、自动化、数据处理与 Web 开发。

  1. 01
    Python 怎么装、怎么用
  2. 02
    变量、数字和字符串
  3. 03
    列表:把一组数据放在一起
  4. 04
    元组、集合和字典正在阅读
  5. 05
    条件判断:让程序做选择
  6. 06
    循环:重复的事交给程序
  7. 07
    函数:把代码整理成可复用的块
  8. 08
    模块与包:拆分你的程序
  9. 09
    输入、输出与字符串格式化
  10. 10
    文件读写:保存程序的数据
  11. 11
    异常处理:程序出错时怎么办
  12. 12
    基础阶段练习:命令行记账本
  13. 13
    类和对象:面向对象入门
  14. 14
    继承、组合与特殊方法
  15. 15
    迭代器与生成器
  16. 16
    列表推导式与生成器表达式
  17. 17
    装饰器:给函数增加能力
  18. 18
    上下文管理器与 with
  19. 19
    类型标注与 dataclass
  20. 20
    正则表达式:从文本中找规律
  21. 21
    日期、时间与时区
  22. 22
    日志与调试
  23. 23
    虚拟环境与依赖管理
  24. 24
    测试:让修改不再提心吊胆
  25. 25
    网络请求:用 Python 调用 API
  26. 26
    网页解析与合规采集
  27. 27
    操作 Excel、CSV 与批量文件
  28. 28
    SQLite:给程序加一个数据库
  29. 29
    数据分析入门:NumPy 与 Pandas
  30. 30
    画图:把数据变得直观
  31. 31
    Flask 入门:做一个小网站
  32. 32
    异步编程:同时处理多项任务
  33. 33
    线程、进程与并发选择
  34. 34
    性能分析与优化
  35. 35
    项目结构、配置与发布
  36. 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() 遍历
  • 选型:要改用列表,锁死用元组,去重用集合,查表用字典

练习

  1. 把字符串 "hello world hello python" 拆成单词,统计每个单词出现几次(提示:split + 字典计数)
  2. 有两个列表 a = [1, 2, 3, 4]b = [3, 4, 5, 6],找出同时在两个列表里的数字(提示:集合交集)
  3. 思考:为什么元组能当字典的键,列表不能?提示:想想字典是靠什么找到值的,列表能不能保证这一点?