当前位置:首页>python>Python3 元组(Tuple):一个上了锁的箱子

Python3 元组(Tuple):一个上了锁的箱子

  • 2026-09-20 18:34:56
Python3 元组(Tuple):一个上了锁的箱子

Python3 元组(Tuple):一个上了锁的箱子

我是陈默,一个正拼命上岸的码农。

你有没有过这种经历?

辛辛苦苦整理好的数据,被一段代码不小心改掉了。找 bug 找了半天,最后发现是一个变量被意外修改。

元组就是 Python 给你的解决方案——一个上了锁的箱子。

装进去的东西,再也改不了。


1. 创建元组:把东西锁进箱子

元组用圆括号 () 表示,元素之间用逗号隔开。

# 创建元组coordinates = (3, 5)colors = ("红", "绿", "蓝")mixed = (1, "hello", 3.14, True)# 空元组empty = ()# 只有一个元素的元组(注意逗号!)single = (42,)print(type(coordinates))    # 输出: <class 'tuple'>print(coordinates)           # 输出: (3, 5)

那个逗号很重要。

a = (42)      # 这不是元组,只是个数字,加了括号而已b = (42,)     # 这才是元组print(type(a))    # 输出: <class 'int'>print(type(b))    # 输出: <class 'tuple'>

这是初学者踩得最多的坑,没有之一。


2. 元组不可修改:上了锁就是上了锁

元组和列表最大的区别——元组创建之后,不能增、删、改。

fruits = ("苹果", "香蕉", "橙子")# 修改?不行fruits[0] = "芒果"# 报错!TypeError: 'tuple' object does not support item assignment# 添加?不行fruits.append("葡萄")# 报错!AttributeError: 'tuple' object has no attribute 'append'# 删除?不行del fruits[0]# 报错!TypeError: 'tuple' object doesn't support item deletion

看起来很不方便,对吧?

但这恰恰是它的价值——你把数据放进元组,就不用担心它被意外修改。


3. 访问元组:和列表一模一样

虽然不能改,但读完全没问题。

索引

fruits = ("苹果", "香蕉", "橙子", "葡萄", "西瓜")print(fruits[0])     # 输出: 苹果print(fruits[2])     # 输出: 橙子print(fruits[-1])    # 输出: 西瓜

切片

fruits = ("苹果", "香蕉", "橙子", "葡萄", "西瓜")print(fruits[1:3])    # 输出: ('香蕉', '橙子')print(fruits[:3])     # 输出: ('苹果', '香蕉', '橙子')print(fruits[2:])     # 输出: ('橙子', '葡萄', '西瓜')print(fruits[::-1])   # 输出: ('西瓜', '葡萄', '橙子', '香蕉', '苹果')

你看,索引和切片的语法,跟列表完全一样。


4. 元组的操作

虽然元组本身不能改,但你可以做一些"不修改"的操作。

拼接

t1 = (1, 2, 3)t2 = (4, 5, 6)result = t1 + t2print(result)    # 输出: (1, 2, 3, 4, 5, 6)

注意:这不是修改原来的元组,而是创建了一个新元组。

重复

t = ("哈",)print(t * 5)    # 输出: ('哈', '哈', '哈', '哈', '哈')

统计和查找

nums = (1, 3, 5, 3, 7, 3, 9)print(len(nums))         # 输出: 7(长度)print(nums.count(3))     # 输出: 3(3 出现了 3 次)print(nums.index(7))     # 输出: 4(7 的位置)print(5in nums)         # 输出: Trueprint(max(nums))         # 输出: 9print(min(nums))         # 输出: 1print(sum(nums))         # 输出: 31

5. 元组解包:一次取出所有值

这是元组最优雅的用法。

基本解包

point = (3, 5)x, y = pointprint(x)    # 输出: 3print(y)    # 输出: 5

一行代码,把元组里的值分别赋给变量。

多变量解包

person = ("陈默", 25, "程序员")name, age, job = personprint(name)    # 输出: 陈默print(age)     # 输出: 25print(job)     # 输出: 程序员

用 * 收集多余的值

scores = (85, 92, 78, 90, 67)first, *rest = scoresprint(first)    # 输出: 85print(rest)     # 输出: [92, 78, 90, 67]first, *middle, last = scoresprint(first)     # 输出: 85print(middle)    # 输出: [92, 78, 90]print(last)      # 输出: 67

交换两个变量

不用临时变量,一行搞定:

a = 10b = 20a, b = b, aprint(a)    # 输出: 20print(b)    # 输出: 10

这背后其实就是元组解包。b, a 先打包成 (20, 10),再分别赋给 a 和 b。


6. 元组 vs 列表:什么时候用哪个?

特性
列表
元组
语法
[]()
可修改
可以
不可以
速度
较慢
较快
可做字典的键
不可以
可以

什么时候用元组?

  • 数据不会变,比如坐标 (x, y)、RGB 颜色 (255, 0, 0)
  • 函数返回多个值
  • 作为字典的键
  • 数据需要保护,防止意外修改

什么时候用列表?

  • 数据会动态增删
  • 需要排序、反转等操作
  • 不确定数据会不会变

简单判断:能不用列表就不用列表,能用元组就用元组。


7. 元组和函数:天生一对

函数返回多个值时,Python 默认用元组:

defget_user_info():    name = "陈默"    age = 25    job = "程序员"return name, age, job    # 其实返回的是一个元组result = get_user_info()print(type(result))    # 输出: <class 'tuple'>print(result)           # 输出: ('陈默', 25, '程序员')# 直接解包接收name, age, job = get_user_info()print(name)    # 输出: 陈默print(age)     # 输出: 25print(job)     # 输出: 程序员

你之前可能一直在用这个特性,只是不知道背后是元组。


8. 实战:用元组管理配置信息

# 数据库配置(这些值不应该被意外修改)DB_CONFIG = ("localhost", 3306, "root", "my_database")host, port, user, database = DB_CONFIGprint(f"连接地址:{host}")print(f"端口:{port}")print(f"用户名:{user}")print(f"数据库:{database}")# 输出:# 连接地址:localhost# 端口:3306# 用户名:root# 数据库:my_database

用元组存配置信息,代码里任何地方都改不了它。

这就是"防呆设计"——不是防别人,是防未来的自己。


最后

元组看起来不如列表灵活,但它的"不可变"恰恰是最大的优点。

记住三件事:

  1. 元组创建后不能修改,这就是它的价值
  2. 单元素元组必须加逗号:(42,) 而不是 (42)
  3. 元组解包是 Python 最优雅的特性之一

我的建议:

回头看看你之前写的代码,有没有哪些列表其实从来不需要修改?试着把它们改成元组。你会发现,代码变得更安全了。

好的代码不是能做更多事,而是让出错变得更难。

今天就到这里。

我是陈默,我们下期再见。


如果你觉得这篇文章有帮助,欢迎关注我。我会持续分享 Python 学习的干货。

最新文章

随机文章