1. 元组是什么? #
- 元组(tuple)是有序、不可变的序列,语法上用圆括号
() 表示(单元素时逗号不能省,见下文)。
- 创建后不能增删改元素;任何「修改」实际上都是生成新元组,原对象不变。
- 与列表相比,元组更轻、语义上表示「固定的一组值」,适合坐标、配置项、函数多返回值等。
- 项目里元组不如列表显眼,但出现频率很高:
(status_code, body)、(host, port)、数据库游标返回的一行 tuple 等。
- 需要频繁追加、排序、原地更新时,应改用列表。
point = (10, 20)
config = ("localhost", 8080)
2. 创建元组 #
- 空元组写
();多个元素用逗号分隔,括号在多数情况下可省略(如 a, b = 1, 2),但为可读性建议保留。
- 最容易踩坑的是单元素元组:必须写成
(42,),末尾逗号不能少。
(42) 只是带括号的整数,类型是 int 不是 tuple。
- 已有列表想转成元组,用
tuple(lst);反向用 list(t)。
- 元组创建后长度与元素固定,没有
append、insert 等方法。
empty = ()
nums = (1, 2, 3)
one = (42,)
also_one = 42,
data = tuple([1, 2, 3])
3. 访问元素 #
- 读取元组元素的方式与列表完全相同:非负/负索引、切片
t[start:end] 规则一致,切片结果仍是元组。
- 区别在于不能对元素重新赋值,
t[0] = "x" 会触发 TypeError,这是「不可变」的核心约束。
- 若元组里嵌套了可变对象(如
([1, 2], 3)),仍不能给 t[0] 整体换成别的对象。
- 但可以修改内层列表的内容——变的是内层对象,不是元组「指向谁」。
- 业务里少用这种嵌套,需要改数据时用列表更直观。
fruits = ("apple", "banana", "orange")
print(fruits[0], fruits[-1])
print(fruits[1:3])
4. 常用操作 #
- 元组支持
+ 拼接两个元组,得到新元组,原元组不变。
- 支持
in、len 等与序列相关的操作。
- 没有
append、sort、remove 等会改变自身的列表方法。
- 需要排序时用
sorted(t) 得到列表,或先 list(t) 再处理。
- 统计类方法只有
count(x)(某值出现次数)和 index(x)(第一次出现的索引)。
- 元素不存在时
index 会抛 ValueError,与列表行为一致。
t1 = (1, 2)
t2 = (3, 4)
print(t1 + t2)
print(2 in t1)
print(len(t1))
t = (1, 2, 3, 2, 1)
print(t.count(2))
print(t.index(3))
5. 元组解包 #
- 解包把元组(或其它可迭代对象)里的元素依次赋给多个变量,是项目里最高频的元组用法之一。
- 函数
return a, b 实际返回的是一个元组。
- 调用方写
code, message = get_status() 比用 result[0]、result[1] 更清晰,也便于类型提示和阅读。
- 用
_ 占位可忽略不需要的值(如中间字段)。
a, b = b, a 交换两变量无需临时变量,底层也是元组解包。
- 解包时变量个数必须与元素个数一致,否则报
ValueError。
def get_status():
return 200, "OK"
code, message = get_status()
print(code, message)
a, b = 10, 20
a, b = b, a
name, _, city = ("Alice", 30, "Beijing")
6. 列表 vs 元组:何时用哪个 #
- 初学阶段可以记一条简单原则:默认用列表存会变的数据。
- 只有确定「这一组值不应被改」或需要可哈希(如当字典键、放进集合)时再用元组。
- 元组不可变,因此可哈希(元素本身也需可哈希);列表可变,不能作为
dict 的键或 set 的元素。
- 函数多返回值、模块级常量、坐标键
(lat, lng) 等场景,元组语义更贴切。
- ORM 查询单行、部分 API 返回
tuple 时,若要原地修改,先 list(row) 再当列表用即可。
| 场景 |
推荐 |
| 需要增删改、动态数据 |
列表 [] |
| 固定配置、常量 |
元组 () |
| 函数返回多个值 |
元组(自动)+ 解包 |
| 作为字典的键 |
元组(列表不可哈希) |
locations = {(31.2, 121.5): "上海"}
7. 项目开发要点 #
- 元组在业务代码里往往是「配角」,但解包、多返回值、常量配置离不开它。
- 默认用列表存业务数据;只有确定「不应被改」时用元组。
- 多返回值用解包:
ok, data = fetch(),比取下标 result[0] 清晰。
- 单元素元组别忘逗号:
(item,) 不是 (item)。
- 不要把元组当列表用:需要
append、排序就改用 list。
- ORM / API 行数据:有时是
tuple,要改就 list(row) 再处理。
- 常量配置:模块级
DB_CONFIG = ("host", 5432) 可防止误改。