6.2 数据类型进阶——元组与 range¶
内容梗概¶
本课讲解元组(tuple)与 range 两种**不可变序列**。先介绍元组的多种创建方式及单元素元组必须带逗号、复杂表达式中不能省略括号等易错点;再通过与列表对照(增加/更新/查找/其他四类操作),说明元组作为不可变序列哪些操作支持、哪些不支持。扩展讲解了可哈希(hashable)概念——不可变对象才能哈希、才能作为字典的 key。随后阐明元组最重要的实际用途:函数返回多个值,防止返回值被意外修改。最后讲解 range 也是不可变序列、支持查找和切片,以及 range 惰性生成、省内存的特性。
知识点详解¶
元组的创建(约 00:01)¶
- 最常规方式:直接用逗号分隔,括号可省略(约 00:19)。用
type()验证类型为 tuple。 - 单元素元组必须带逗号(约 00:42):
(1,)才是元组,(1)只是数字 1。 - 在较长表达式/语句中不能省略括号(约 01:32):老师现场演示了经典错误——把元组作为函数参数时省略括号,会被拆成多个参数导致报错。
tuple()构造(约 01:44):只能接收**一个**参数,且该参数须为**可迭代对象**(列表、元组本身都可以)。tuple(列表)可把列表转为元组。
元组与列表操作的异同(约 02:42)¶
判断原则:凡是**修改序列本身内容**的操作(增加、更新类),元组都不支持,因为它是不可变序列。
- 不支持:
reverse(约 04:48,课堂提问互动)、append/insert/extend、pop、remove、clear、切片赋值、给某下标赋值(如a[0] = x报错)。 - 支持:
- 查找类:
min、max、index、count(约 05:45); - 切片(约 06:04):取出的元素放进新元组,不改变原元组,完全可行;
- 拼接:
a + b生成新元组(约 12:01 例子:教师队伍 teachers 元组想"加人",拼接另一个元组存到新变量); - 整体删除:
del a把整个元组变量删掉是允许的(约 08:13),报错信息是"变量不存在"而非"不能删"。 - 没有
copy方法(约 07:17):元组未定义copy,但可以用完整切片a[:]得到一个一模一样的新元组(有点坑人,容易想当然)。
扩展:可哈希(hashable)(约 09:25)¶
- 字典底层是哈希表,key 要用哈希值计算。
- 规则:不可变对象可以哈希,可变对象不能哈希(
hash()对列表报错,对字符串、元组正常)。 - 推论:字符串和元组可以作为字典的 key,列表不行。为 6.4 字典做铺垫。
元组的典型用途:函数返回多个值(约 13:38)¶
- 用列表返回多值也能实现,但大型项目中返回值可能在别处被意外修改(如
result[0] = ...),导致后续逻辑出错且难以排查。 - 用元组返回(
return 年龄, 名字, 性别,括号可省略),任何修改尝试都会直接报错——类似 C 语言const的效果。 - 惯例:函数返回多个值默认用元组;更复杂的结构化数据可用字典(结构更清晰,但可被修改)。
range(约 18:26)¶
- range 本身也是**不可变序列**,支持不可变序列的所有操作:
index、count、甚至切片(约 19:05 演示range(10).index(7)返回 7)。 - 为什么用 range(约 20:23):range 在**迭代过程中才逐个生成数字**,不一次性占用内存。对比:生成一个上千万元素的列表约占 10 MB 内存,而
range无论多大都占用极小空间。 - 实践建议:实际项目中循环计数基本都用 range,不要直接循环超大列表,要有节约内存的意识。
- 课件末尾附有一张"列表/元组/range 支持操作对照表"(约 22:38),供课后自查。
示例与演示¶
type(1,)/type(1)验证单元素元组逗号的必要性。- 老师现场"翻车"演示:在函数参数位置省略元组括号导致被拆成多个参数——借此强调复杂表达式中括号不可省。
- 课堂互动提问:"元组能用
reverse吗?"(不能,因为属于修改内容的操作)。 - 定义元组后演示
min/max打印、index/count查找、取前两个元素的切片。 - 教师队伍例子(约 12:01):只有一个元素的元组
teachers,想加入新教师 → 拼接新元组得到新变量;演示拼接、完整切片"copy"、查找、hash()、del整体删除(代码供课后自行运行)。 - 函数返回多值例子(约 14:07 起):
get_information()函数假装从文件/数据库读取后return age, name, gender;对比用列表返回被意外赋值修改、用元组返回赋值即报错。 - range 内存对比例子(约 20:53):
for i in range(10000000...)(很多个 0)配合pass,说明同样循环用列表要占约 10 MB 而 range 几乎不占空间。
重点与难点¶
- 单元素元组必须写逗号:
(1,)。 - 元组在较长表达式/函数参数中**不能省略括号**,否则被拆成多个参数。
tuple()只接收一个可迭代对象参数。- 元组**没有**
copy方法,用a[:]代替;没有一切修改内容的操作,但del整体删除可以。 - 可哈希规则:不可变才可哈希、才能当字典的 key;列表不可哈希。
- 函数返回多个值**默认用元组**,防止返回值被意外修改。
- range 是惰性序列,循环计数首选 range 而非大列表(内存意识)。
关联内容¶
- 紧承 6.1 列表的操作分类框架(增加/更新/查找/其他),逐一对比元组的支持情况。
- 可哈希概念为 6.4 字典(key 的要求)直接铺垫;哈希表概念关联后续数据结构课程。
- 函数返回多值关联前面函数章节;"类"的概念留待面向对象章节。
- range 关联之前的 for 循环与列表推导式(6.1 中
extend(range(20,30))已用到)。 - 课件附列表/元组/range 操作对照表,建议课后自行核对。