Kodewick
第 10 课,共 31 课目录

元组

第 10 课,共 31 课 · 第 2 部分 · 容器和循环 · 约 15 分钟

元组就像一个不能改的列表。把各项写在圆括号里,而不是方括号里。几个值属于一起、也一直在一起的时候,就用元组,比如镇上地图里一盏灯的列和行。

main.py
1lamp = (4, 7)2print(lamp)3print(type(lamp))4print(len(lamp))
输出
(4, 7)
<class 'tuple'>
2

创建元组

其实造出元组的是逗号,括号主要是为了好读。只有一项的元组,这一项后面要加逗号;不然括号只是分组,和数学里的括号一样。

main.py
1size = 3, 52print(size)3one = ("煤",)4print(one, len(one))5empty = ()6print(empty, len(empty))7print(tuple(["甲", "乙"]))
输出
(3, 5)
('煤',) 1
() 0
('甲', '乙')
先猜一猜

这段会显示什么?

1x = (5)2print(type(x))

读取元组

能读列表的办法都能读元组:下标、切片、len、in、min、max、sum、sorted。

main.py
1week = ("周一", "周二", "周三", "周四", "周五", "周六", "周日")2print(week[0], week[-1])3print(week[5:])4print("周日" in week)5print(week[2:4])6scores = (8, 3, 9, 3)7print(max(scores), min(scores), sum(scores))8print(sorted(scores))
输出
周一 周日
('周六', '周日')
True
('周三', '周四')
9 3 23
[3, 3, 8, 9]

sorted 返回的总是列表,哪怕你给它的是元组。

元组不能改

元组一旦造好,里面的项就不能改、不能加、也不能删。没有 append,没有 remove,给下标赋值会报错:

main.py
1lamp = (4, 7)2print(lamp[0])3lamp[0] = 5
输出
4
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    lamp[0] = 5
TypeError: 'tuple' object does not support item assignment

发生了什么: 类型不对:拿了一种东西去做另一种东西才能做的事。

想要一个不一样的元组,就造一个新的。+ 把几个元组接成一个新元组;新的值可以再交给原来的名字。

main.py
1lamp = (4, 7)2lamp = (5, lamp[1])3print(lamp)4path = (1, 2) + (3,)5print(path)
输出
(5, 7)
(1, 2, 3)

为什么要一个不能改的东西?因为这样就不会被不小心改掉。一组地图坐标,写下来是什么,就一直是什么。

拆包

在 = 左边写好几个名字,Python 会按顺序把元组里的项一个一个交给它们,这叫拆包。列表也能这样拆。

main.py
1lamp = (4, 7)2col, row = lamp3print("第", col, "列,第", row, "行")4name, age, town = ("Wick", 9, "灯火镇")5print(name, "今年", age, "岁")
输出
第 4 列,第 7 行
Wick 今年 9 岁

名字的个数要和项数一样,不然会报 ValueError:

main.py
1col, row = (4, 7, 2)
输出
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    col, row = (4, 7, 2)
ValueError: too many values to unpack (expected 2)

发生了什么: 值不对:类型是对的,但这个值用不了。

其实你已经用过拆包了。a, b = b, a 交换两个变量:右边先造出元组 (b, a),左边再把它拆开。

先猜一猜

这段会显示什么?

1a = 12b = 23a, b = b, a + b4print(a, b)

一次得到几个结果

有些函数的答案不止一个,就返回一个元组。divmod(a, b) 同时给出 a // b 和 a % b。把结果拆开,每个答案就有了自己的名字。

main.py
1print(divmod(17, 5))2boxes, left = divmod(17, 5)3print("装满", boxes, "箱,还剩", left, "块矿石")4hours, mins = divmod(150, 60)5print(hours, "小时", mins, "分钟")
输出
(3, 2)
装满 3 箱,还剩 2 块矿石
2 小时 30 分钟

第 16 课你会自己写函数,也用这种办法一次返回几个值。

元组还是列表?

列表 [ ]元组 ( )
能不能改能不能
改动它的方法很多(append、sort 等)没有
常见用法一组同类的东西,会变多变少固定的一条记录,比如位置、日期
例子今天路线上的街名(4, 7),一盏灯的位置

用 list() 和 tuple() 互相转换。常见的做法:先把元组转成列表,改好,再转回来。

main.py
1date = (2026, 11, 1)2parts = list(date)3parts[2] = 24date = tuple(parts)5print(date)
输出
(2026, 11, 2)

小技巧: 元组能当字典的键、能放进集合,列表不行。接下来两课你会看到这为什么重要。

练一练

写好代码,点检查。提示随便看,实在想不出来再看答案。

练习 1

拆开一盏灯

把 lamp 拆成三个变量,按下面的样子显示出来。

要显示
磨坊巷 3 True
exercise1.py
1lamp = ("磨坊巷", 3, True)2# 在这里写
输出
点「运行」或按 Ctrl+Enter
练习 2

挪一挪灯

元组不能改,所以给 lamp 造一个新元组:列加一,行不变。

要显示
(5, 7)
exercise2.py
1lamp = (4, 7)2lamp[0] = lamp[0] + 13print(lamp)
输出
点「运行」或按 Ctrl+Enter
练习 3

分和秒

用 divmod 把 135 秒换成几分几秒,用 f-string 显示出来。

要显示
2 分 15 秒
exercise3.py
1seconds = 1352# 在这里写
输出
点「运行」或按 Ctrl+Enter

这一课学会了

  • 元组是一组有顺序、不能改的值:(4, 7)。只有一项时要加逗号:(5,)。
  • 读法和列表一样:下标、切片、len、in、max、sorted。
  • 改其中一项会报 TypeError;要改就造一个新元组。
  • 拆包让每一项有自己的名字:col, row = lamp。个数要对上。
  • divmod 返回元组;拆开就能分别用。
  • 会变的一组东西用列表;固定的一条记录用元组。