第 12 课 · 入门 · 18 分钟

Python 元组与集合

固定记录用元组,唯一值集合用 set,让数据结构的意图更清楚。

元组解包集合去重成员判断

套餐永远是饮料加杯型——正好两个值,不会是三个。配料却是一堆没有顺序、也不能重复的加料。哪种容器能用形状把这两件事说清楚?

列表不是 Python 里唯一的集合类型。元组把固定数量的值组合起来,创建后不能修改;集合保存唯一值,成员判断很快。知道该选哪一种,代码的意图会更清楚。 你还会返回固定形状的记录、用集合判断成员关系,并比较权限集合。

元组是固定记录

元组用圆括号表示,保留值的顺序。你可以按索引读取,也可以一次解包到多个变量。元组创建后不能修改,因此适合坐标、键值对,或本来就应该保持不变的记录。

point = (3, 5)
x, y = point
print(x + y)

解包元组

集合保存唯一值

set 会去掉重复项,但不保证显示顺序。当“是否唯一”或“是否存在”比位置更重要时,就用集合。把列表转成集合,是统计不同值的快捷方式。

orders = ["latte", "tea", "latte"]
unique = set(orders)
print(len(unique))
print("tea" in unique)

去重与成员判断

集合运算

& 取两个集合的交集,| 取并集。需要稳定输出顺序时,先对结果排序。不要依赖集合本身的显示顺序。

a = {1, 2, 3}
b = {3, 4}
print(sorted(a & b))
print(sorted(a | b))

交集与并集

元组是固定形状,不是短列表

字段数量本身就是含义时,用元组。divmod() 返回商和余数,解包可以一次给两个名字。带星号的目标会收集剩下的值,适合“表头加可变尾部”的记录。

quotient, remainder = divmod(17, 5)
print(quotient, remainder)
record = ("2026-10-28", "latte", 4.5, "paid")
date, drink, *rest = record
print(date, drink)
print(rest)

形状固定时,按位置解包

集合回答的是成员问题

集合去重,并能快速回答 in。它不保证插入顺序,所以显示前先排序。需要历史顺序或保留重复项时,仍然用列表;只有“唯一”是目标时才转成集合。

visits = ["home", "menu", "home", "checkout"]
unique_pages = set(visits)
print(len(unique_pages))
print(sorted(unique_pages))
print("menu" in unique_pages)
print("help" in unique_pages)

唯一值,不是时间线

用子集和差集比较权限

集合运算可以表达权限规则。required <= granted 问的是“必需权限是否齐全”;granted - required 列出多余项,required - granted 列出缺口。交集非空,比子集判断弱得多。

required = {"read", "write"}
granted = {"read", "write", "admin"}
print(required <= granted)
print(sorted(granted - required))
print(sorted(required - granted))
print(sorted(required ^ granted))

子集判断权限是否完整

本课要点

  • 元组保留顺序,不能原地修改。
  • 元组解包会把每个值赋给一个变量。
  • 集合去重,并支持快速的成员判断。
  • 需要顺序时,打印集合前先排序。
  • 固定记录用元组,唯一性和成员判断用集合。

常见错误

  • 试图对元组调用 append,而不是创建新元组。
  • 以为集合会保留原列表顺序。
  • 只关心值是否存在时,仍然使用列表。
  • 只检查交集是否非空,却忘了每个必需权限都要存在。
轮到你

创建一个包含名称和价格的元组,解包后打印格式化句子。

动手试试

改改变量、先预测输出,再运行代码。第一次点击“运行代码”时会下载 Python 运行时,可能需要几秒钟。

浏览器内 Python本地运行 · 无需账号
首次运行会从 CDN 下载 Pyodide。修改后点击“运行代码”。

练习本课

12 道题,作答后立即看到解释。

查看 12 道题答案开始练习
← while 循环推导式 →