查看全课大纲(第 23 / 51 节)
  1. 1.Python 是什么?为什么值得学?
  2. 2.如何为 Python 编程准备一个“全家桶”环境?
  3. 3.Python 有哪几种执行方法?
  4. 4.行与缩进到底有什么用?
  5. 5.注释有什么用,怎么写?
  6. 6.变量:如何给数据起个好名字?
  7. 7.运算符的优先级和常见坑点是什么?
  8. 8.Python 中,数字和布尔值究竟有哪几种?
  9. 9.输入函数 `input()` 和文件读取 `open()` 怎么用?
  10. 10.如何将程序的结果展示给用户或保存下来?
  11. 11.CSV 文件怎么读怎么写才方便?
  12. 12.列表是什么,如何创建和访问它?
  13. 13.列表的修改操作,有哪些方法?
  14. 14.列表切片为什么能取到部分元素?排序和查找又该怎么用?
  15. 15.判断语句:如何让程序根据条件做不同的事?
  16. 16.for 循环如何遍历序列中的元素?
  17. 17.while 循环什么时候才会停?
  18. 18.while 循环的结束条件,你写对了吗?
  19. 19.循环中途想提前结束,怎么办?
  20. 20.`break` 和 `continue` 到底有什么区别?
  21. 21.列表推导式如何让代码更简洁高效?
  22. 22.字符串怎么定义、拼接和操作?
  23. 23.元组:为什么定义单个元素时要加逗号?
  24. 24.集合(set)怎么用?如何快速去重和做集合运算?
  25. 25.字典是什么,为什么比列表更方便?
  26. 26.字典的增删改查与遍历,如何避免 KeyError?
  27. 27.函数里的变量,为什么有的能用有的不能用?
  28. 28.在函数内部修改全局变量,为什么有时不生效?
  29. 29.函数里能修改全局变量吗?返回值怎么用?
  30. 30.匿名函数:如何用 lambda 快速定义简单函数?
  31. 31.面向对象编程是什么,为什么需要它?
  32. 32.类中的方法和属性到底怎么定义和使用?
  33. 33.如何控制对对象内部属性和方法的访问?
  34. 34.异常发生时,程序会怎样继续执行?
  35. 35.如何组织代码:包和模块
  36. 36.`if __name__ == '__main__'` 到底有什么用?
  37. 37.如何用 IDE 的 Debug 功能排查程序错误?
  38. 38.Matplotlib 绘图的第一步该做什么?
  39. 39.Figure 是什么,如何设置图形尺寸?
  40. 40.如何自定义 Matplotlib 的坐标轴?
  41. 41.如何为图表添加图例,让不同曲线一目了然?
  42. 42.饼图怎么画才能直观展示数据占比?
  43. 43.如何用 Matplotlib 绘制散点图?
  44. 44.柱状图怎么画?
  45. 45.如何使用 Matplotlib 绘制等高线图?
  46. 46.如何在 Matplotlib 中绘制子图?
  47. 47.zip 函数如何把多个列表“打包”在一起?
  48. 48.如何给可迭代对象加上索引?
  49. 49.random 模块如何生成随机数?
  50. 50.math 模块怎么用?
  51. 51.Counter 如何快速统计元素出现次数?

元组:为什么定义单个元素时要加逗号?

约 9 分钟

小象实战讲义 · Python 编程从入门到实践

在学习了列表之后,我们迎来了另一种重要的序列类型——元组。元组和列表很像,都能按顺序存储多个元素,但有一个关键区别:元组是不可变的。学完本节,你将掌握元组的定义、访问和遍历方法,并理解其不可变特性带来的使用限制与常见陷阱。本节是《更多数据结构》章节的一部分,承接列表的知识,为后续学习字典、集合等数据结构打下基础。

💡 核心导读

  • 定义与结构:元组用逗号分隔元素,通常用圆括号括起来,但括号并非必需。
  • 核心特性:不可变性。一旦创建,元组的内容(元素)不能被修改、添加或删除。
  • 访问与遍历:通过下标(索引)访问元素,下标从 0 开始。可以使用 for 循环或 while 循环遍历。
  • 特殊定义:定义只包含一个元素的元组时,必须在元素后面加一个逗号,否则 Python 会将其识别为其他类型。
  • 典型用途:适合存储一组不应被修改的数据,例如本节示例中的数据库连接信息。

元组是什么?

元组(tuple)是 Python 中用于顺序存储多个元素的数据结构。这些元素可以是相同类型,也可以是不同类型(例如,同时包含字符串和数字)。

元组的定义语法很简单:元素之间用逗号 , 分隔。为了代码清晰,我们通常会用一对圆括号 () 将所有元素括起来,这也能让元组和列表等其他序列类型区分开(字典是键值映射,不属于序列),但这不是语法强制要求的。

元组最核心的特性是不可变(immutable)。这意味着一旦一个元组被创建,你就不能对它进行添加新元素、修改已有元素或删除元素的操作。你只能“读取”或“访问”它。

如何定义和访问元组?

1. 基本定义、访问与省略括号

定义元组时,用逗号分隔元素,并用括号括起是常见做法。访问元素则使用下标(索引),下标从 0 开始,与列表完全相同。括号可以省略,但逗号不能省略。

# 定义一个包含数据库连接信息的元组:IP地址,端口,用户名,密码
db_info = ("192.168.1.1", 3306, "root", "root123")
print(type(db_info))

# 通过下标访问元素
print("IP地址:", db_info[0])
print("数据库端口:", db_info[1])
print("最后一个元素(密码):", db_info[3])

# 省略括号的定义方式
tuple_a = 3, 2
tuple_b = (3, 2)
print("tuple_a 的值:", tuple_a)
print("tuple_b 的值:", tuple_b)
print("两者相等吗?", tuple_a == tuple_b)
print("tuple_a 下标为1的元素是:", tuple_a[1])
<class 'tuple'>
IP地址: 192.168.1.1
数据库端口: 3306
最后一个元素(密码): root123
tuple_a 的值: (3, 2)
tuple_b 的值: (3, 2)
两者相等吗? True
tuple_a 下标为1的元素是: 2

2. 空元组与单元素元组

  • 空元组:使用一对空的圆括号定义。
  • 单元素元组:这是元组定义中的一个易错点。如果只有一个元素,必须在元素后面加上一个逗号 ,,否则 Python 不会将其识别为元组。
# 定义一个空元组
empty_tuple = ()
print("空元组类型:", type(empty_tuple))

# 正确定义一个只包含一个元素的元组
one_tuple = (123,)   # 注意元素后的逗号
print("单元素元组类型:", type(one_tuple))
print("单元素元组内容:", one_tuple)

# 错误示例:漏掉逗号会怎样?
not_a_tuple = (123)  # 这只是一个加了括号的数字
print("漏掉逗号的'元组'类型:", type(not_a_tuple))
print("漏掉逗号的'元组'内容:", not_a_tuple)
空元组类型: <class 'tuple'>
单元素元组类型: <class 'tuple'>
单元素元组内容: (123,)
漏掉逗号的'元组'类型: <class 'int'>
漏掉逗号的'元组'内容: 123

为什么需要逗号? 在 Python 中,圆括号 () 除了用来定义元组,还用来改变算术运算的优先级。(123) 对 Python 来说,只是一个被括号括起来的整数表达式,其结果就是整数 123。为了消除歧义,明确告诉 Python“这是一个元组”,就必须在单一元素后加上逗号。

如何遍历元组?

遍历元组就是依次访问其中的每一个元素,方法和遍历列表一样:for 循环最简洁;while 循环则配合下标和长度使用。

db_info = ("192.168.1.1", 3306, "root", "root123")

print("使用 for 循环遍历:")
for item in db_info:
    print(item)

print("使用 while 循环遍历:")
i = 0
while i < len(db_info):  # len() 函数获取元组长度
    print(db_info[i])
    i += 1  # 不要忘记更新下标,否则会陷入无限循环
使用 for 循环遍历:
192.168.1.1
3306
root
root123
使用 while 循环遍历:
192.168.1.1
3306
root
root123

元组的“不可变”意味着什么?

“不可变”是元组的根本特性:元组自身不支持添加、修改或删除元素,尝试这些操作会引发 TypeError。

# 以下两种操作都会报错,不能执行
db_info = ("192.168.1.1", 3306, "root", "root123")
db_info[1] = 8080   # TypeError: 'tuple' object does not support item assignment
del db_info[1]      # TypeError: 'tuple' object doesn't support item deletion

所以,一旦定义了一个元组变量,就只能对它进行访问,不能改动其中的元素。

📝 动手练一练

  1. 理解单元素元组:请写出两种不同的代码,分别产生以下输出结果:
    • 第一行输出:<class 'str'>
    • 第二行输出:<class 'tuple'> 提示:都需要用到圆括号。
👉 点击查看参考答案

思路:要得到字符串类型,可以用括号包裹一个字符串字面量。要得到元组类型,必须使用逗号。

# 产生字符串类型
var1 = ("hello")
print(type(var1))

# 产生元组类型
var2 = ("hello",)  # 关键在逗号
print(type(var2))
<class 'str'>
<class 'tuple'>
  1. 元组存储与访问:假设你需要存储一个点的坐标 (x, y) 和一个颜色名称,请定义一个元组 point_info 来存储 (5, 10, "蓝色"),然后分别将 x 坐标、y 坐标和颜色提取到三个变量中并打印。
👉 点击查看参考答案

思路:利用元组的下标访问特性,将对应位置的元素赋值给不同的变量。

# 定义元组
point_info = (5, 10, "蓝色")

# 通过下标访问并赋值
x_coord = point_info[0]
y_coord = point_info[1]
color_name = point_info[2]

print("X坐标:", x_coord)
print("Y坐标:", y_coord)
print("颜色:", color_name)
X坐标: 5
Y坐标: 10
颜色: 蓝色

常见错误

错误写法现象或报错原因正确写法
single = (1)变量 single 的类型是 int,不是 tuple。括号被解释为改变运算优先级,单一元素后缺少逗号,Python 不认为这是元组。single = (1,)
my_tuple = (1, 2, 3) 后执行 my_tuple[1] = 99TypeError: 'tuple' object does not support item assignment元组是不可变类型,创建后不能修改其元素。如果需要可变的序列,应使用列表:my_list = [1, 2, 3] 后执行 my_list[1] = 99
db_info = ("192.168.1.1", 3306) 后执行 del db_info[1]TypeError: 'tuple' object doesn't support item deletion元组不可变,也不能删除其中某个元素。只能重新定义一个不含该元素的新元组。

小结

  1. 元组用于存储有序的元素序列,元素间用逗号分隔,常用圆括号括起来。
  2. 元组的核心特性是不可变,创建后无法添加、修改或删除元素,只能访问。
  3. 访问元组元素使用下标(索引),从 0 开始。
  4. 定义只含一个元素的元组时,必须在元素后加逗号,例如 (x,),否则会被识别为其他类型。
  5. 定义元组时圆括号可以省略(如 x, y),但逗号是必须的。
  6. 遍历元组可以使用 for item in tuple 或 while 循环配合下标。

📋 行动清单

  • 在代码编辑器中,尝试定义一个包含你姓名、年龄、城市的元组,并练习用下标访问每个信息。
  • 故意写一段尝试修改元组元素的代码,运行并观察 Python 给出的错误信息。
  • 将本节遍历元组的 for 循环例子,改用 while 循环实现,确保输出结果一致。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第3章代码包:元组(含1 个 Notebook)
    ZIP · 911B
    下载