Python 中元组完全指南
文章目录
- [Python 中元组完全指南](#Python 中元组完全指南)
-
- 第一部分:元组是什么?
- [第二部分:元组 vs 列表](#第二部分:元组 vs 列表)
- 第三部分:元组解包(解构赋值)
- 第四部分:元组用在实际项目中(如读取配置文件)
- 第五部分:元组的典型应用场景
- 第六部分:元组不可变,但内部可变对象可被修改
- 第七部分:不能修改元组的元素,但可以给变量重新赋值
- 第八部分:综合示例与小结
https://www.quanzhankaige.com/python09/
本文档面向零基础新手,详细讲解 元组(tuple) 是什么、与列表的区别、元组解包 、在实际项目中的用法(如配置文件),以及典型应用场景(函数返回多值、字典的键、解构赋值);并说明元组的"不可变"含义、元组内可变对象可修改、以及"给变量重新赋值"的用法。
第一部分:元组是什么?
一、元组的概念
元组 是 Python 里的一种有序、可重复 的数据结构,和列表很像,但有一个根本区别:元组是不可变的------创建之后不能增、删、改元素。
基本写法: 用圆括号 () 把多个元素括起来,元素之间用逗号 , 分隔。
python
# 空元组
empty = ()
print(empty) # ()
# 多个元素
point = (10, 20)
colors = ("红", "绿", "蓝")
mixed = (1, "hello", 3.14, True)
print(point, colors, mixed)
只有一个元素的元组: 必须在后面加逗号,否则括号会被当成运算括号。
python
# 错误:没有逗号时,(1) 只是整数 1
x = (1)
print(type(x)) # <class 'int'>
# 正确:单元素元组要加逗号
t = (1,)
print(type(t)) # <class 'tuple'>
print(t) # (1,)
二、访问元组元素(索引与切片)
和列表一样,用索引 取一个元素、用切片取一段。索引从 0 开始,-1 表示最后一个。
python
t = ("A", "B", "C", "D")
print(t[0]) # A
print(t[-1]) # D
print(t[1:3]) # ('B', 'C')(切片得到的是新元组)
三、元组没有"改、增、删"元素的方法
因为元组不可变 ,所以没有 append、insert、remove、pop 等方法,也不能用 元组[索引] = 新值 赋值。
python
t = (1, 2, 3)
# t[0] = 10 # 报错:TypeError
# t.append(4) # 报错:元组没有 append
# t.remove(2) # 报错:元组没有 remove
第二部分:元组 vs 列表
四、对比小结
| 项目 | 列表 list | 元组 tuple |
|---|---|---|
| 写法 | [1, 2, 3] |
(1, 2, 3) |
| 可变性 | 可增删改 | 不可变(不能增删改元素) |
| 方法 | append、insert、remove、sort 等 | 只有 count、index 等不修改自身的方法 |
| 适用场景 | 需要动态修改的序列 | 固定结构、不希望被改、作字典键等 |
何时用元组:
- 数据不需要也不应该被修改(如坐标、配置项、函数返回的多个值)
- 需要把序列当作字典的键(列表不能当键,元组可以)
- 希望语义明确:"这是一组固定的值"
何时用列表:
- 需要随时增删改元素时用列表。
python
# 坐标、RGB 等"固定一组值"适合元组
point = (100, 200)
rgb = (255, 0, 0)
# 待办事项、动态收集的数据适合列表
todos = ["写代码", "测试"]
todos.append("提交")
第三部分:元组解包(解构赋值)
五、什么是元组解包?
元组解包 (也叫解构赋值 )是指:把元组里的多个元素一次性赋给多个变量,左边变量个数要和元组元素个数一致(或用 * 收集多余元素)。
基本写法:
python
t = (10, 20)
a, b = t
print(a) # 10
print(b) # 20
等价于:a = t[0]; b = t[1],但更简洁。
常见写法:右边直接写元组(甚至省略括号)
python
# Python 中右边多个值用逗号隔开,本身就是元组
x, y = 10, 20
print(x, y) # 10 20
name, age = "小明", 18
print(name, age) # 小明 18
交换两个变量:
python
a, b = 1, 2
a, b = b, a
print(a, b) # 2 1
元素个数必须匹配(否则报错),除非用 * 收集:
python
# a, b = (1, 2, 3) # 报错:太多
# a, b, c = (1, 2) # 报错:太少
# 用 * 把多余的元素收集成一个列表
first, *rest = (1, 2, 3, 4)
print(first) # 1
print(rest) # [2, 3, 4]
六、解包在循环中的应用
遍历"元组的列表"时解包:
python
points = [(1, 2), (3, 4), (5, 6)]
for x, y in points:
print("x =", x, "y =", y)
遍历字典的 .items() 时解包:
python
d = {"name": "小明", "age": 18}
for key, value in d.items():
print(key, value)
第四部分:元组用在实际项目中(如读取配置文件)
七、配置项、常量用元组表示
很多项目里会把"不会在运行中改动的配置"放在元组或元组组成的结构中,表示"只读"。
示例:简单配置(用元组表示一组选项或键)
python
# 允许的扩展名(固定集合)
ALLOWED_EXTENSIONS = ("jpg", "jpeg", "png", "gif")
# 默认配置项(名称, 默认值)成对
DEFAULT_CONFIG = (
("host", "localhost"),
("port", 8080),
("debug", False),
)
# 遍历配置
for name, value in DEFAULT_CONFIG:
print(name, "=", value)
示例:从"配置文件结构"中读取(模拟)
python
# 模拟从配置文件读出的多组 (键, 值),用元组列表表示
config_items = [
("database.host", "127.0.0.1"),
("database.port", 3306),
("app.name", "MyApp"),
]
config = dict(config_items) # 转成字典方便用
print(config["database.host"]) # 127.0.0.1
元组在这里的作用:每一行配置是 (键, 值) 的固定结构,用元组保证不被误改,且可哈希,必要时可作字典键。
第五部分:元组的典型应用场景
八、函数返回多个值
函数用 return 多个值 时,Python 会把这多个值打包成一个元组返回;接收时可以直接用元组解包。
python
def get_user():
name = "小明"
age = 18
return name, age # 相当于 return (name, age)
# 解包接收
user_name, user_age = get_user()
print(user_name, user_age) # 小明 18
# 也可以整体接收为一个元组
info = get_user()
print(info) # ('小明', 18)
九、字典的键
字典的键 必须不可变 。列表可变,不能当键;元组不可变,可以当键(只要元组里的元素也都是不可变类型)。
python
# 用元组表示"坐标"作为键
location_names = {
(0, 0): "原点",
(1, 0): "东",
(0, 1): "北",
}
print(location_names[(1, 0)]) # 东
# 列表不能当键
# bad = { [1,2]: "错误" } # TypeError: unhashable type: 'list'
十、解构赋值(元组解包)作为典型用法
"解构赋值"本身就是元组的典型用法:多变量同时赋值、交换变量、在 for 中解包、用 * 收集多余元素等,前面已写,这里不再重复。
第六部分:元组不可变,但内部可变对象可被修改
十一、元组"不可变"指什么?
不可变 指的是:元组本身 不能增删元素,也不能把某个位置改成另一个对象 (不能 t[0] = 新值)。
但这不限制 元组里某个元素如果是可变对象 (如列表、字典),那个对象内部是可以被修改的。
python
t = (1, [2, 3], 4)
# t[0] = 10 # 报错:不能改元组里的"引用"
# t[1] = [5, 6] # 报错:不能把 t[1] 换成别的对象
# 但 t[1] 指向的列表内部可以改
t[1].append(99)
print(t) # (1, [2, 3, 99], 4)
理解: 元组里存的是"引用"(指向对象的指针)。元组不能改的是"这一格必须一直指向同一个对象";对象本身若是列表,列表里的内容可以增删改。
再示例:元组里是字典
python
t = ({"a": 1},)
t[0]["b"] = 2 # 可以:改的是字典内部
print(t) # ({'a': 1, 'b': 2},)
第七部分:不能修改元组的元素,但可以给变量重新赋值
十二、给"存储元组的变量"重新赋值
元组对象 一旦创建就不能改,但变量 可以随时指向新的对象。所以你可以让变量先指向一个元组,再让同一个变量指向另一个元组(或列表等)。
python
t = (1, 2, 3)
t = (4, 5, 6) # 没有改原来的 (1,2,3),而是让 t 指向新元组
print(t) # (4, 5, 6)
t = [1, 2, 3] # 变量也可以改为指向列表
print(t) # [1, 2, 3]
区别:
- 不能做 :
t[0] = 10(修改元组里的元素)→ 报错 - 可以做 :
t = (10, 20, 30)(让变量 t 指向新的元组)
第八部分:综合示例与小结
十三、综合示例
python
# 1. 元组创建与访问
point = (10, 20)
print(point[0], point[-1])
# 2. 元组解包
x, y = point
print(x, y)
# 3. 函数返回多值
def min_max(nums):
return min(nums), max(nums)
lo, hi = min_max([3, 1, 4, 1, 5])
print(lo, hi) # 1 5
# 4. 字典键用元组
d = {(1, 2): "A", (3, 4): "B"}
print(d[(1, 2)])
# 5. 元组内列表可修改
t = (1, [2, 3])
t[1].append(4)
print(t) # (1, [2, 3, 4])
# 6. 变量可重新赋值为新元组
t = (1, 2)
t = (3, 4)
print(t) # (3, 4)
十四、小结表
| 内容 | 要点 |
|---|---|
| 元组 | 用 () 表示,有序、可重复、不可变(不能增删改元素) |
| 元组 vs 列表 | 列表可变、元组不可变;固定结构、键、多返回值等用元组 |
| 元组解包 | a, b = 元组 或 a, b = 值1, 值2;可配合 * 收集 |
| 实际项目 | 配置项、常量、键值对结构可用元组(或元组列表)表示 |
| 典型场景 | 函数返回多值、字典的键、解构赋值 |
| 不可变含义 | 不能改元组元素本身;若元素是列表/字典,其内部可改 |
| 变量赋值 | 不能 元组[i]=新值,但可以 变量 = 新元组 |