Python元组(Tuple)全部高级用法大全
很多 Python 新手刚学元组时,第一反应是:
元组不就是不能修改的列表吗?
这个理解没错,但只说对了一半。元组确实和列表很像,都能存多个数据;但元组在实际开发里还有很多常见用法,比如函数返回多个值、多变量赋值、数据解包、作为字典键、保存配置常量、防止数据被误改等。
这篇文章用大白话把 Python 元组从基础到高级完整讲一遍。每个知识点都配有可运行代码、示例数据、运行结果和实际使用场景,适合 Python 新手收藏复盘。
1. 先回顾:什么是元组?
元组英文叫 tuple,它可以保存多个数据。
最常见写法是用小括号 ():
# 创建一个元组
person = ("小王", 18, "Python")
print(person)
print(type(person))
运行结果:
('小王', 18, 'Python')
<class 'tuple'>
你可以把元组理解成一个固定内容的数据包。创建好以后,里面的元素不能被直接修改。
person = ("小王", 18, "Python")
print(person[0])
print(person[1])
print(person[2])
运行结果:
小王 18 Python
实际使用场景:
- 保存一个人的固定信息,比如姓名、年龄、技能。
- 保存接口返回的多个结果。
- 保存不会被修改的配置项。
新手先记住一句话:
元组适合存一组固定数据,列表适合存一组经常变化的数据。
2. 元组 VS 列表:核心区别
元组和列表很像,但它们最大的区别是:
| 对比项 | 元组 tuple | 列表 list |
|---|---|---|
| 写法 | ("A", "B") | ["A", "B"] |
| 是否可修改 | 不可直接修改 | 可以修改 |
| 常用场景 | 固定数据、配置、函数返回值 | 增删改数据 |
| 能否作为字典键 | 满足条件时可以 | 不可以 |
| 语义 | 数据不希望被改 | 数据后续可能变化 |
看代码更直观:
# 列表可以修改
names_list = ["小王", "小李"]
names_list[0] = "小张"
print(names_list)
# 元组不能直接修改
names_tuple = ("小王", "小李")
print(names_tuple)
运行结果:
['小张', '小李']
('小王', '小李')
如果你强行修改元组,会报错:
names_tuple = ("小王", "小李")
names_tuple[0] = "小张"
运行结果:
TypeError: 'tuple' object does not support item assignment
实际使用场景:
- 需要修改数据,用列表。
- 不希望数据被误改,用元组。
- 一组数据只是用来读取、传递、返回,用元组很合适。
新手避坑:
- 元组不是“更高级的列表”,它们只是用途不同。
- 不要为了看起来高级就乱用元组。
- 如果后面要频繁增加、删除、修改元素,直接用列表。
3. 单元素元组正确写法与避坑
这是新手最容易踩的坑。
很多人以为这样就是单元素元组:
value = ("Python")
print(value)
print(type(value))
运行结果:
Python <class 'str'>
它不是元组,而是字符串。因为小括号在这里只是普通分组。
单元素元组必须加逗号。
value = ("Python",)
print(value)
print(type(value))
运行结果:
('Python',)
<class 'tuple'>
数字也一样:
a = (100) b = (100,) print(type(a)) print(type(b))
运行结果:
<class 'int'> <class 'tuple'>
实际使用场景:
- 函数参数需要传入元组时,哪怕只有一个元素,也要写成
(value,)。 - 数据库查询参数只有一个值时,经常需要单元素元组。
- 某些接口要求参数类型必须是元组。
新手避坑:
- 判断单元素元组,看逗号,不看小括号。
("Python")是字符串。("Python",)才是元组。
4. 元组可以不写小括号吗?
可以。Python 里真正决定元组的,很多时候是逗号。
point = 10, 20 print(point) print(type(point))
运行结果:
(10, 20) <class 'tuple'>
这也是元组。
不过新手建议先写小括号,因为更清楚:
point = (10, 20) print(point)
运行结果:
(10, 20)
实际使用场景:
- 多变量赋值时经常省略小括号。
- 函数返回多个值时,底层其实返回的是元组。
新手避坑:
- 虽然能省略小括号,但代码太复杂时建议写上,别人更容易读懂。
- 单元素元组不能只写小括号,必须写逗号。
5. 元组解包:一次取出多个值
元组解包就是把元组里的值,一次性分给多个变量。
person = ("小王", 18, "Python")
name, age, skill = person
print(name)
print(age)
print(skill)
运行结果:
小王 18 Python
可以理解成:
name 接收 "小王" age 接收 18 skill 接收 "Python"
实际使用场景:
- 接收函数返回的多个结果。
- 读取固定格式的数据。
- 让代码更清楚,不用反复写下标。
对比一下不用解包的写法:
person = ("小王", 18, "Python")
print(person[0])
print(person[1])
print(person[2])
运行结果:
小王 18 Python
虽然也能用,但 person[0]、person[1] 对新手来说不够直观。解包后变量名更清楚。
新手避坑:
- 左边变量数量要和元组元素数量一致。
错误示例:
person = ("小王", 18, "Python")
name, age = person
运行结果:
ValueError: too many values to unpack (expected 2)
原因是右边有 3 个值,左边只有 2 个变量,接不住。
6. 多变量赋值:优雅交换变量
Python 里可以用元组思想做多变量赋值。
a, b = 10, 20 print(a) print(b)
运行结果:
10 20
最经典的用法是交换两个变量:
a = 10 b = 20 # 交换 a 和 b 的值 a, b = b, a print(a) print(b)
运行结果:
20 10
实际使用场景:
- 交换两个变量。
- 同时接收多个配置值。
- 同时初始化多个变量。
示例:同时保存坐标。
x, y = 100, 200
print(f"x 坐标:{x}")
print(f"y 坐标:{y}")
运行结果:
x 坐标:100 y 坐标:200
新手避坑:
a, b = b, a不是魔法,可以理解为右边先打包成一个临时元组,再解包给左边。- 左边变量数量和右边值数量仍然要匹配。
7. 星号 * 不定长解包
如果元组里的元素数量不固定,可以用星号 * 接收多余的元素。
scores = (90, 85, 70, 60, 100) first, *middle, last = scores print(first) print(middle) print(last)
运行结果:
90 [85, 70, 60] 100
注意:*middle 接收到的是一个列表,不是元组。
再看一个只取前两个,其余打包的例子:
data = ("小王", "Python", "北京", "后端开发")
name, skill, *others = data
print(name)
print(skill)
print(others)
运行结果:
小王 Python ['北京', '后端开发']
实际使用场景:
- 只关心头尾数据,中间数据统一收起来。
- 接收接口返回的不定长数据。
- 处理 CSV、日志、命令行参数这类字段数量可能变化的数据。
新手避坑:
- 一个解包语句里只能有一个星号变量。
错误示例:
nums = (1, 2, 3, 4) *left, *right = nums
运行结果:
SyntaxError: multiple starred expressions in assignment
正确写法:
nums = (1, 2, 3, 4) first, *rest = nums print(first) print(rest)
运行结果:
1 [2, 3, 4]
8. 忽略不需要的值:用下划线 _
有些值你不想用,可以用 _ 接住。
person = ("小王", 18, "Python")
name, _, skill = person
print(name)
print(skill)
运行结果:
小王 Python
这里 _ 表示这个值我不关心。
实际使用场景:
- 数据格式固定,但只需要其中几个字段。
- 函数返回多个值,只用其中一部分。
示例:
def get_user_info():
return ("小王", 18, "北京")
name, _, city = get_user_info()
print(name)
print(city)
运行结果:
小王 北京
新手避坑:
_只是一个普通变量名,不是真的“消失”。- 它只是约定俗成地表示“不使用这个值”。
a, _ = (10, 20) print(_)
运行结果:
20
9. 元组嵌套使用
元组里面还可以放元组,这叫嵌套元组。
student = ("小王", (90, 85, 88), "一班")
print(student)
运行结果:
('小王', (90, 85, 88), '一班')
这个数据可以理解为:
学生姓名:小王 成绩:90, 85, 88 班级:一班
实际使用场景:
- 封装结构化数据。
- 保存坐标点,比如
(x, y)、(x, y, z)。 - 保存一条记录里的多个子信息。
示例:多个坐标点。
points = ((0, 0), (10, 20), (30, 40)) print(points)
运行结果:
((0, 0), (10, 20), (30, 40))
新手避坑:
- 嵌套层级不要太深。
- 如果数据字段很多、结构复杂,可以考虑字典或类,别把元组写成“套娃”。
10. 嵌套元组取值
嵌套元组取值,就是一层一层用下标。
student = ("小王", (90, 85, 88), "一班")
name = student[0]
scores = student[1]
english_score = student[1][1]
print(name)
print(scores)
print(english_score)
运行结果:
小王 (90, 85, 88) 85
student[1][1] 的意思是:
student[1] 先拿到 (90, 85, 88) student[1][1] 再拿这个元组里的第 2 个元素
还可以配合解包:
student = ("小王", (90, 85, 88), "一班")
name, (math_score, english_score, chinese_score), class_name = student
print(name)
print(math_score)
print(english_score)
print(chinese_score)
print(class_name)
运行结果:
小王 90 85 88 一班
实际使用场景:
- 读取固定格式的复杂数据。
- 处理二维坐标、三维坐标。
- 解析接口返回的简单嵌套结构。
新手避坑:
- 下标从
0开始。 - 下标写错会取到错误字段。
- 嵌套结构太复杂时,不要硬用元组,字典可能更清楚。
11. 元组与列表互相转换
元组可以转列表,列表也可以转元组。
names_tuple = ("小王", "小李", "小张")
names_list = list(names_tuple)
print(names_list)
print(type(names_list))
运行结果:
['小王', '小李', '小张'] <class 'list'>
列表转元组:
names_list = ["小王", "小李", "小张"] names_tuple = tuple(names_list) print(names_tuple) print(type(names_tuple))
运行结果:
('小王', '小李', '小张')
<class 'tuple'>
实际使用场景:
- 元组需要临时修改时,先转成列表,改完再转回元组。
- 列表数据处理完成后,转成元组防止后续误改。
- 某些函数要求传入元组类型。
示例:修改元组内容的常见思路。
colors = ("red", "green", "blue")
# 元组不能直接改,先转成列表
colors_list = list(colors)
colors_list[1] = "yellow"
# 改完再转回元组
colors = tuple(colors_list)
print(colors)
运行结果:
('red', 'yellow', 'blue')
新手避坑:
- 这不是“直接修改元组”,而是创建了一个新的元组。
- 如果你经常要改,说明一开始就应该用列表。
12. 元组与字典互相转换
元组经常和字典配合使用,尤其是二元组。
二元组列表可以转成字典:
pairs = (("name", "小王"), ("age", 18), ("skill", "Python"))
user = dict(pairs)
print(user)
运行结果:
{'name': '小王', 'age': 18, 'skill': 'Python'}
字典也可以转成由键值对组成的元组:
user = {"name": "小王", "age": 18, "skill": "Python"}
items_tuple = tuple(user.items())
print(items_tuple)
运行结果:
(('name', '小王'), ('age', 18), ('skill', 'Python'))
实际使用场景:
- 接口返回的键值对数据转成字典。
- 把字典内容固定下来,防止后续随便改结构。
- 批量处理键值对。
新手避坑:
- 转字典时,每个小元组必须是两个元素:键和值。
错误示例:
pairs = (("name", "小王", "多余字段"), ("age", 18))
user = dict(pairs)
运行结果:
ValueError: dictionary update sequence element #0 has length 3; 2 is required
13. 元组与集合互相转换
元组转集合可以去重。
nums = (1, 2, 2, 3, 3, 3) unique_nums = set(nums) print(unique_nums)
运行结果:
{1, 2, 3}
集合转元组:
nums_set = {3, 1, 2}
nums_tuple = tuple(nums_set)
print(nums_tuple)
运行结果示例:
(1, 2, 3)
注意:集合本身没有固定顺序,不同环境下输出顺序可能不一样。
如果你想稳定排序,可以这样:
nums = (3, 1, 2, 2, 3) result = tuple(sorted(set(nums))) print(result)
运行结果:
(1, 2, 3)
实际使用场景:
- 元组数据去重。
- 判断数据是否重复。
- 把去重后的结果重新固定成元组。
新手避坑:
set()会去重,但不保证原顺序。- 想要稳定顺序,配合
sorted()。
14. 元组拼接:用 + 合并
元组可以用 + 拼接。
base_info = ("小王", 18)
extra_info = ("Python", "北京")
user_info = base_info + extra_info
print(user_info)
运行结果:
('小王', 18, 'Python', '北京')
实际使用场景:
- 合并固定字段。
- 给已有元组追加一段信息。
- 拼接多个接口返回结果。
新手避坑:
- 元组拼接不会修改原元组,而是生成新元组。
a = (1, 2) b = (3, 4) c = a + b print(a) print(b) print(c)
运行结果:
(1, 2) (3, 4) (1, 2, 3, 4)
如果频繁拼接大量数据,不建议反复用 +,可以先用列表收集,最后转元组。
15. 元组重复:用 * 快速生成固定数据
元组可以用 * 重复。
flags = ("未处理",) * 5
print(flags)
运行结果:
('未处理', '未处理', '未处理', '未处理', '未处理')
注意单元素元组还是要写逗号:("未处理",)。
实际使用场景:
- 快速生成默认状态。
- 快速生成固定长度的占位数据。
- 初始化简单配置。
示例:
default_scores = (0,) * 4 print(default_scores)
运行结果:
(0, 0, 0, 0)
新手避坑:
("未处理") * 5得到的是字符串重复,不是元组重复。
wrong = ("未处理") * 3
right = ("未处理",) * 3
print(wrong)
print(right)
运行结果:
未处理未处理未处理
('未处理', '未处理', '未处理')
16. 快速合并技巧:星号展开多个元组
除了 +,还可以用星号 * 展开元组,再重新打包。
a = (1, 2) b = (3, 4) c = (5, 6) result = (*a, *b, *c) print(result)
运行结果:
(1, 2, 3, 4, 5, 6)
这种写法在需要同时插入新元素时很方便:
old_data = ("小王", 18)
new_data = (*old_data, "Python", "北京")
print(new_data)
运行结果:
('小王', 18, 'Python', '北京')
实际使用场景:
- 合并多个固定数据包。
- 在原有数据前后追加字段。
- 构造函数参数。
新手避坑:
*在这里表示“展开”,不是乘法。- 展开后重新用小括号包起来,得到新的元组。
17. zip() 搭配元组批量配对数据
zip() 可以把多个序列按位置配对,返回一组一组的元组。
names = ("小王", "小李", "小张")
scores = (90, 85, 88)
for item in zip(names, scores):
print(item)
运行结果:
('小王', 90)
('小李', 85)
('小张', 88)
也可以直接解包:
names = ("小王", "小李", "小张")
scores = (90, 85, 88)
for name, score in zip(names, scores):
print(f"{name} 的成绩是 {score}")
运行结果:
小王 的成绩是 90 小李 的成绩是 85 小张 的成绩是 88
实际使用场景:
- 批量配对姓名和成绩。
- 批量配对商品和价格。
- 批量配对字段名和值。
示例:字段名和值转字典。
fields = ("name", "age", "skill")
values = ("小王", 18, "Python")
user = dict(zip(fields, values))
print(user)
运行结果:
{'name': '小王', 'age': 18, 'skill': 'Python'}
新手避坑:
zip()会按最短的序列停止。
names = ("小王", "小李", "小张")
scores = (90, 85)
print(list(zip(names, scores)))
运行结果:
[('小王', 90), ('小李', 85)]
小张 没有对应成绩,所以被丢掉了。
18. enumerate() 结合元组遍历
enumerate() 可以在遍历元组时,同时拿到序号和值。
skills = ("Python", "SQL", "Linux")
for index, skill in enumerate(skills):
print(index, skill)
运行结果:
0 Python 1 SQL 2 Linux
如果想让序号从 1 开始:
skills = ("Python", "SQL", "Linux")
for index, skill in enumerate(skills, start=1):
print(f"{index}. {skill}")
运行结果:
1. Python 2. SQL 3. Linux
实际使用场景:
- 给菜单编号。
- 给排行榜编号。
- 遍历固定配置项时输出序号。
示例:打印菜单。
menus = ("查看余额", "转账", "退出")
for number, menu in enumerate(menus, start=1):
print(f"{number}. {menu}")
运行结果:
1. 查看余额 2. 转账 3. 退出
新手避坑:
- 只需要序号和值,用
enumerate()比range(len(...))更清楚。 enumerate()返回的每一项本质上也是一个二元组,比如(0, "Python")。
skills = ("Python", "SQL")
print(list(enumerate(skills)))
运行结果:
[(0, 'Python'), (1, 'SQL')]
19. 元组不可变的实际优势
元组不可变,不只是限制,也是优势。
19.1 防止数据被误改
config = ("localhost", 3306, "root")
print(config)
运行结果:
('localhost', 3306, 'root')
如果有人想直接改:
config = ("localhost", 3306, "root")
config[1] = 3307
运行结果:
TypeError: 'tuple' object does not support item assignment
实际使用场景:
- 数据库连接配置。
- 系统固定选项。
- 坐标、颜色、状态码等不希望随便被改的数据。
19.2 表达“只读数据”的意图
roles = ("admin", "editor", "guest")
for role in roles:
print(role)
运行结果:
admin editor guest
看到元组,别人就知道这组角色一般不应该被随便改。
实际使用场景:
- 权限角色列表。
- 固定菜单项。
- 不允许动态添加的枚举值。
新手避坑:
- 元组不可变,指的是元组里“每个位置的引用”不能改。
- 如果元组里面放了列表,列表本身还是可以改。
data = ("小王", ["Python", "SQL"])
data[1].append("Linux")
print(data)
运行结果:
('小王', ['Python', 'SQL', 'Linux'])
这点很容易误解。元组不允许你把 data[1] 换成别的对象,但 data[1] 这个列表自身可以修改。
20. 元组作为字典键
字典的键要求是可哈希的,简单理解就是:这个键本身不能随便变。
元组如果里面的元素也都是不可变数据,就可以作为字典键。
locations = {
(0, 0): "起点",
(10, 20): "商店",
(30, 40): "医院"
}
print(locations[(10, 20)])
运行结果:
商店
实际使用场景:
- 用坐标作为字典键。
- 用多个字段组合成唯一标识。
- 缓存函数计算结果。
示例:用姓名和城市作为组合键。
users = {
("小王", "北京"): "后端开发",
("小李", "上海"): "数据分析"
}
print(users[("小王", "北京")])
运行结果:
后端开发
新手避坑:
- 元组里如果包含列表,就不能作为字典键。
bad_key = ("小王", ["Python", "SQL"])
data = {
bad_key: "测试"
}
运行结果:
TypeError: unhashable type: 'list'
因为列表是可变的,放进元组后,整个元组也不能安全地作为字典键。
21. 函数返回多值:本质就是元组
Python 函数可以返回多个值。
def get_user():
return "小王", 18, "Python"
result = get_user()
print(result)
print(type(result))
运行结果:
('小王', 18, 'Python')
<class 'tuple'>
函数看起来返回了 3 个值,本质上是返回了一个元组。
通常我们会直接解包:
def get_user():
return "小王", 18, "Python"
name, age, skill = get_user()
print(name)
print(age)
print(skill)
运行结果:
小王 18 Python
实际使用场景:
- 函数同时返回状态和结果。
- 函数同时返回最大值、最小值、平均值。
- 接口封装时返回多个相关信息。
示例:
def analyze_scores(scores):
total = sum(scores)
average = total / len(scores)
return total, average
total_score, average_score = analyze_scores((90, 80, 70))
print(total_score)
print(average_score)
运行结果:
240 80.0
新手避坑:
- 返回多个值时,接收变量数量要一致。
- 如果只关心其中一个值,可以用
_忽略其他值。
def analyze_scores(scores):
total = sum(scores)
average = total / len(scores)
return total, average
_, average_score = analyze_scores((90, 80, 70))
print(average_score)
运行结果:
80.0
22. 函数参数打包:*args
函数定义里写 *args,可以接收不确定数量的位置参数。
这些参数会被打包成一个元组。
def show_numbers(*args):
print(args)
print(type(args))
show_numbers(10, 20, 30)
运行结果:
(10, 20, 30) <class 'tuple'>
实际使用场景:
- 函数参数数量不固定。
- 写求和、打印、批量处理这类通用函数。
示例:自定义求和。
def my_sum(*numbers):
total = 0
for number in numbers:
total += number
return total
print(my_sum(1, 2, 3))
print(my_sum(10, 20, 30, 40))
运行结果:
6 100
新手避坑:
args这个名字可以换,但习惯上都写*args。*args接收到的是元组,不是列表。
23. 函数参数解包:把元组拆开传进去
如果函数需要多个参数,而你手里有一个元组,可以用 * 把元组拆开传进去。
def introduce(name, age, skill):
print(f"我叫{name},今年{age}岁,会{skill}")
user = ("小王", 18, "Python")
introduce(*user)
运行结果:
我叫小王,今年18岁,会Python
如果不用 *,会把整个元组当成第一个参数,参数数量就不对。
def introduce(name, age, skill):
print(name, age, skill)
user = ("小王", 18, "Python")
introduce(user)
运行结果:
TypeError: introduce() missing 2 required positional arguments: 'age' and 'skill'
实际使用场景:
- 参数已经被封装成元组。
- 批量调用函数。
- 从配置、接口或数据库里读出参数后直接传给函数。
新手避坑:
- 函数需要几个参数,元组里就要有几个值。
*user表示把元组拆开,不是乘法。
24. len():获取元组长度
len() 可以获取元组里有多少个元素。
skills = ("Python", "SQL", "Linux")
print(len(skills))
运行结果:
3
实际使用场景:
- 判断数据字段数量是否正确。
- 判断配置项是否完整。
- 遍历时确认数据规模。
示例:
user = ("小王", 18, "Python")
if len(user) == 3:
print("用户信息完整")
else:
print("用户信息不完整")
运行结果:
用户信息完整
新手避坑:
len()统计的是顶层元素数量,不会自动统计嵌套元组里的元素。
data = ("小王", (90, 80, 70))
print(len(data))
运行结果:
2
25. max()、min():获取最大值和最小值
元组里如果都是可比较的数据,可以用 max() 和 min()。
scores = (90, 85, 100, 60) print(max(scores)) print(min(scores))
运行结果:
100 60
实际使用场景:
- 获取最高分、最低分。
- 获取最大价格、最小价格。
- 获取最大编号、最小编号。
示例:
prices = (199, 299, 99, 399)
print(f"最高价格:{max(prices)}")
print(f"最低价格:{min(prices)}")
运行结果:
最高价格:399 最低价格:99
新手避坑:
- 不要把数字和字符串混在一起比较。
data = (100, "200", 300) print(max(data))
运行结果:
TypeError: '>' not supported between instances of 'str' and 'int'
26. sum():对数字元组求和
sum() 可以对数字元组求和。
scores = (90, 85, 100) total = sum(scores) print(total)
运行结果:
275
实际使用场景:
- 计算总分。
- 计算总金额。
- 计算总数量。
示例:计算平均分。
scores = (90, 85, 100) total = sum(scores) average = total / len(scores) print(total) print(average)
运行结果:
275 91.66666666666667
新手避坑:
sum()只能对数字求和。
data = ("Python", "SQL")
print(sum(data))
运行结果:
TypeError: unsupported operand type(s) for +: 'int' and 'str'
字符串拼接不要用 sum(),可以用 join()。
data = ("Python", "SQL")
print(" + ".join(data))
运行结果:
Python + SQL
27. count():统计某个元素出现次数
count() 用来统计某个值在元组里出现了几次。
levels = ("初级", "中级", "初级", "高级", "初级")
print(levels.count("初级"))
print(levels.count("高级"))
运行结果:
3 1
实际使用场景:
- 统计某个状态出现次数。
- 统计某个标签出现次数。
- 统计考试等级、订单状态、任务状态。
示例:
statuses = ("成功", "失败", "成功", "处理中", "成功")
success_count = statuses.count("成功")
print(f"成功次数:{success_count}")
运行结果:
成功次数:3
新手避坑:
count()只统计完全相等的值。
words = ("Python", "python", "PYTHON")
print(words.count("Python"))
运行结果:
1
大小写不同,结果就不同。
28. index():查找元素位置
index() 可以查找某个元素第一次出现的位置。
skills = ("Python", "SQL", "Linux", "Python")
print(skills.index("Python"))
print(skills.index("Linux"))
运行结果:
0 2
注意:index() 返回的是第一次出现的位置。
实际使用场景:
- 查找某个状态所在位置。
- 查找某个菜单项编号。
- 查找固定配置项的位置。
示例:
menus = ("首页", "课程", "订单", "我的")
position = menus.index("订单")
print(position)
运行结果:
2
新手避坑:
- 如果元素不存在,
index()会报错。
menus = ("首页", "课程", "订单", "我的")
print(menus.index("设置"))
运行结果:
ValueError: tuple.index(x): x not in tuple
更安全的写法:
menus = ("首页", "课程", "订单", "我的")
target = "设置"
if target in menus:
print(menus.index(target))
else:
print("没有找到")
运行结果:
没有找到
29. 什么时候必须用元组?
严格来说,很多时候列表和元组都能完成任务。但下面几种情况,元组更合适,甚至必须用。
29.1 想作为字典键
point_names = {
(0, 0): "原点",
(1, 2): "目标点"
}
print(point_names[(1, 2)])
运行结果:
目标点
列表不能作为字典键:
point_names = {
[0, 0]: "原点"
}
运行结果:
TypeError: unhashable type: 'list'
29.2 想表达数据不应该被修改
database_config = ("127.0.0.1", 3306, "root")
print(database_config)
运行结果:
('127.0.0.1', 3306, 'root')
配置数据通常不希望运行过程中随便被改,元组更能表达这个意思。
29.3 函数返回多个值
def get_range_info(numbers):
return min(numbers), max(numbers)
small, big = get_range_info((8, 3, 10, 1))
print(small)
print(big)
运行结果:
1 10
Python 返回多个值时,本质就是元组。
29.4 固定结构的数据
rgb = (255, 128, 0) red, green, blue = rgb print(red) print(green) print(blue)
运行结果:
255 128 0
RGB 颜色值固定就是 3 个数字,用元组非常合适。
30. 新手高频易错点总结
30.1 单元素元组忘记逗号
wrong = ("Python")
right = ("Python",)
print(type(wrong))
print(type(right))
运行结果:
<class 'str'> <class 'tuple'>
30.2 以为元组绝对不能变
data = ("小王", ["Python"])
data[1].append("SQL")
print(data)
运行结果:
('小王', ['Python', 'SQL'])
元组位置不能改,但里面的可变对象自己还能改。
30.3 解包数量不匹配
info = ("小王", 18, "Python")
name, age = info
运行结果:
ValueError: too many values to unpack (expected 2)
解决办法是变量数量匹配,或者使用 * 接收多余值。
info = ("小王", 18, "Python")
name, *others = info
print(name)
print(others)
运行结果:
小王 [18, 'Python']
30.4 index() 查不到元素会报错
skills = ("Python", "SQL")
target = "Java"
if target in skills:
print(skills.index(target))
else:
print("没有这个技能")
运行结果:
没有这个技能
30.5 把元组当列表频繁修改
如果你写代码时总是这样:
data = ("A", "B", "C")
data_list = list(data)
data_list.append("D")
data = tuple(data_list)
print(data)
运行结果:
('A', 'B', 'C', 'D')
说明你可能一开始就应该用列表。
31. 元组实战:封装用户数据并批量处理
最后用一个接近实际开发的小例子,把元组、解包、zip()、enumerate() 串起来。
# 用户字段和用户数据
fields = ("name", "age", "skill")
users = (
("小王", 18, "Python"),
("小李", 20, "SQL"),
("小张", 22, "Linux")
)
for index, user in enumerate(users, start=1):
# zip 把字段名和值配对,再转成字典
user_dict = dict(zip(fields, user))
print(f"第 {index} 个用户")
print(user_dict)
运行结果:
第 1 个用户
{'name': '小王', 'age': 18, 'skill': 'Python'}
第 2 个用户
{'name': '小李', 'age': 20, 'skill': 'SQL'}
第 3 个用户
{'name': '小张', 'age': 22, 'skill': 'Linux'}
这个例子里:
fields是固定字段,用元组保存。users是多条固定结构的数据,用嵌套元组保存。enumerate()负责生成序号。zip()负责把字段和值配对。dict()负责把配对结果转成字典。
实际使用场景:
- 处理数据库查询结果。
- 处理接口返回的多条记录。
- 把固定格式的数据批量转成字典。
32. 知识点总结
这篇文章讲了 Python 元组的基础和高级用法,新手重点记住下面这些:
- 元组用来保存一组固定数据,创建后不能直接修改元素。
- 单元素元组必须写逗号,比如
("Python",)。 - 元组可以解包,比如
name, age = ("小王", 18)。 - 星号
*可以做不定长解包,比如first, *rest = data。 - 元组可以嵌套,适合保存简单的结构化数据。
- 元组可以和列表、字典、集合互相转换,但要注意转换后的数据特性。
- 元组可以拼接和重复,但都会生成新元组,不会修改原元组。
- zip() 常用于批量配对数据,返回的是一组组元组。
- enumerate() 常用于遍历元组时同时拿序号和值。
- 元组不可变能防止误改,适合配置常量、固定选项、只读数据。
- 元组可以作为字典键,前提是里面的元素也都不可变。
- 函数返回多个值,本质上就是返回元组。
- 函数里的
*args会把多个参数打包成元组。 - 调用函数时
*tuple可以把元组拆开传参。 - 常用函数和方法包括
len()、max()、min()、sum()、count()、index()。
最后再用一句话收尾:
如果数据后面要改,用列表;如果数据固定、不希望被误改、要作为组合键或函数返回多个值,用元组。
把这个判断记住,Python 元组就不难了。
以上就是Python元组(Tuple)全部高级用法大全的详细内容,更多关于Python元组(Tuple)高级用法的资料请关注脚本之家其它相关文章!
相关文章
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
这篇文章主要介绍了python绕过图片滑动验证码实现爬取PTA所有题目 附源码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-01-01
tensorflow模型文件(ckpt)转pb文件的方法(不知道输出节点名)
这篇文章主要介绍了tensorflow模型文件(ckpt)转pb文件(不知道输出节点名),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-04-04


最新评论