Python元组 tuple 和集合 set
较难4概述:元组是只读的列表,集合是没有重复元素的无序盒子。
Python元组和集合:不变的便签和自动去重的百宝袋
除了之前学过的列表(可变的有序盒子)和字典(键值对映射),Python 还提供了两种特别实用的数据类型:元组(tuple) 和 集合(set)。它们各有各的脾气,学会之后能让你的代码更安全、更高效。下面我们就来分别认识它们。
1. 元组(tuple):写上去就不能改的便签纸
元组长得像列表,但一旦创建,里面的元素就不能修改、增加或删除——就像一张写满字后贴死的便签纸。它用圆括号 () 来表示。
创建元组
# 用圆括号包裹,元素用逗号隔开
triangle_sides = (3, 4, 5) # 三角形的三条边长,固定不变
print(triangle_sides[0]) # 可以访问,输出 3
# triangle_sides[0] = 6 # 这行如果执行会报错!元组不允许修改
如果元组只有一个元素,记得在它后面加一个逗号,否则 Python 会当成普通的数字或字符串:
single_tuple = (99,) # 正确:一个元素的元组
not_tuple = (99) # 错误:这只是整数 99,不是元组
print(type(single_tuple)) # <class 'tuple'>
print(type(not_tuple)) # <class 'int'>
元组的特点:只读、有序、可重复
- 只读:不能修改、添加、删除任何元素。
- 有序:元素有固定的顺序,可以用下标
[索引]来访问(从0开始)。 - 可重复:允许有相同元素,比如
(1,2,1)是合法的。
生活中的例子
- 一年中的月份:12个月份的名字是固定的,绝不会变。
months = ("一月", "二月", "三月", "四月", "五月", "六月",
"七月", "八月", "九月", "十月", "十一月", "十二月")
print(months[0]) # 一月
- 固定坐标点:比如你家的经纬度
(116.4, 39.9),不会随意改动。 - 计算中的常量:比如圆周率
(3.14, 3.1416)可以存进元组备用。
为什么用元组而不是列表?
| 场景 | 推荐用元组 | 理由 |
|---|---|---|
| 数据不应该被修改 | 三角形的三边长度 | 避免意外改动导致错误 |
| 作为字典的键 | 字典的键必须是不可变的 | 元组可以,列表不行 |
| 函数返回多个值 | 返回一个元组 | 安全、简洁 |
新手容易犯的错误
- 试图修改元组:
t = (1,2,3); t[1] = 100→ 报错TypeError。记住:元组不支持赋值。 - 忘记单元素元组的逗号:
t = (1)是整数,不是元组。调试时记得检查类型。
2. 集合(set):自动去重的“百宝袋”
集合就像一个魔法袋子,你往里丢东西,它会自动去掉重复的,而且不讲究顺序。它用花括号 {} 表示,但注意:空集合必须用 set() 创建,因为 {} 是空字典。
创建集合
# 用花括号直接创建
guests = {"小明", "小红", "小刚", "小明"} # 小明重复了,集合自动保留一个
print(guests) # 输出可能是 {'小红', '小刚', '小明'},顺序随机
# 创建空集合必须用 set()
empty_set = set() # 空集合
# empty_set = {} # 这其实是空字典,不是集合!
集合的特点:无序、不重复、元素必须可哈希(不可变)
- 无序:元素没有固定的顺序,每次打印的顺序可能不同。不能通过下标访问。
- 不重复:重复元素只保留一个。
- 元素类型:只能放不可变的数据(数字、字符串、元组),不能放列表或字典。
生活中的例子
- 活动签到名单:一个人不能重复签到,用集合自动去重。
- 班级里不同的兴趣小组:统计所有参加的同学,去掉重复。
- 数学中的集合:交集(都参加的人)、并集(所有参加的人)非常直观。
常用操作:添加、删除、长度
students = {"小刚", "小丽"} # 初始名单
students.add("小明") # 添加一个人
students.add("小丽") # 小丽已在,不影响
print(students) # 输出:{'小刚', '小丽', '小明'}
students.remove("小刚") # 删除一个人,如果不存在会报错
students.discard("小红") # 更安全:不存在不会报错
print(len(students)) # 输出 2(小丽、小明)
集合的数学运算:交集、并集、差集
假设一班和二班都参加了运动会:
class1 = {"小明", "小红", "小刚"}
class2 = {"小刚", "小丽", "小亮"}
# 交集:两个班都参加的人(同时属于两个集合)
both = class1 & class2
print("共同参加的人:", both) # {'小刚'}
# 并集:所有参加的人(合并两个集合,去掉重复)
all_students = class1 | class2
print("全部参加的人:", all_students) # {'小刚', '小亮', '小红', '小丽', '小明'}
# 差集:只在一班但不在二班的人
only_class1 = class1 - class2
print("仅一班参加的人:", only_class1) # {'小明', '小红'}
新手容易犯的错误
- 混淆集合和字典:
{}默认是字典,只有用{元素1, 元素2}才是集合。空集合必须用set()。 - 试图用下标访问:
s = {1,2,3}; print(s[0])→ 报错,因为集合无序,没有索引。 - 把可变元素(如列表)放入集合:
s = {[1,2]}→ 报错,因为列表不可哈希。
3. 完整示例:班级考试信息管理
下面我们把元组和集合结合起来,处理一个班级的小任务:记录两名学生的考试成绩(不可变),然后统计班级参加补考的学生名单(去重)。
# ---------- 元组部分:存储每个学生的成绩 ----------
score_xiaoming = (95, 88, 92) # 小明三门课的分数(语文, 数学, 英语)
score_xiaohong = (87, 93, 90) # 小红三门课的分数
print("小明的成绩:", score_xiaoming) # 输出 (95, 88, 92)
# score_xiaoming[0] = 100 # 如果取消注释会报错,成绩不能随意改
# ---------- 集合部分:记录需要补考的学生名单 ----------
# 假设考试不及格(低于60分)需要补考
need_retake = set() # 空集合,用来存放要补考的同学
# 判断小明是否需要补考
if score_xiaoming[0] < 60 or score_xiaoming[1] < 60 or score_xiaoming[2] < 60:
need_retake.add("小明")
# 判断小红是否需要补考
if score_xiaohong[0] < 60 or score_xiaohong[1] < 60 or score_xiaohong[2] < 60:
need_retake.add("小红")
# 再加一个同学小刚,他数学没及格
need_retake.add("小刚")
need_retake.add("小明") # 小明已经在了,不会重复添加
print("需要补考的同学:", need_retake) # 输出类似 {'小明', '小刚'}(小红全及格,不在集合中)
# ---------- 集合运算:求与另一个小班的交集 ----------
class_a = {"小明", "小红", "小刚", "小丽"}
class_b = {"小刚", "小亮", "小明"}
# 两个班都挂科的同学(交集)
fail_both = need_retake & class_b
print("B班需要补考的同学:", fail_both) # 输出 {'小刚', '小明'}
# 所有需要补考的同学(合并两个班)
all_fail = need_retake | class_b
print("所有需要补考的同学:", all_fail) # 输出 {'小刚', '小亮', '小明'}
运行这段代码,会看到元组保护了成绩不被修改,集合自动去重并帮助我们进行交集、并集运算。这就是元组和集合在日常编程中的典型用途。
4. 相关知识点指引
- 列表:元组的“可变兄弟”,可以自由增删改。当你需要频繁修改数据时用列表。
- 字典:另一种用花括号的有序映射,但键必须不可变(元组可用作键)。
- 字符串:本质上也是不可变的序列,像元组一样只能读不能改。
- 进阶知识:元组拆包(交换变量、函数返回多个值)、集合的
frozenset(不可变集合)、列表与集合互相转换(去重技巧)。
学会了元组和集合,你的 Python 工具箱就更丰富了。遇到“不想被改”的数据,果断用元组;遇到“要去重”或“做数学集合运算”的需求,优先考虑集合。多练几次,你会越来越喜欢它们!
例题精讲
1单选题
下列哪个操作会引发 TypeError?
At = (1, 2, 3); t[1] = 4
Bt = (1, 2, 3); print(t[1])
Ct = (1, [2,3], 4); t[1][0] = 5
Dt = [1,2,3]; t[1] = 4
2单选题
关于集合的说法,正确的是?
A集合中的元素可以是列表
B集合中的元素必须是不可变类型
C集合是有序的
D集合可以包含重复元素
3判断题
元组 (1, 2, 3) 可以通过 t[0] = 10 修改元素值。
4填空题
请补全代码,创建一个只包含整数5的元组并赋值给变量t:
t = ___5填空题
已知集合 a = {1, 2, 3},b = {2, 3, 4},请计算它们的交集并赋值给变量 c:
c = ___