PYTHON 基础教程(第 3 版)· 第 2 章

列表元组

序列 —— 一次装下一整班同学的姓名与成绩
高中信息技术 · Python 程序设计授课时长 90 分钟 讲练一体 · 代码可现场运行共 64 页
开场 · ROADMAP

今天这 90 分钟,我们这样走

课堂时间轴(分钟)
0–10
导入
10–36
通用序列操作
36–72
列表方法
72–86
元组
86–90
总结
序列是什么
索引 / 切片 / 相加 / 乘法 / 成员
增删改查 + 排序 + 引用陷阱
不可变序列
回顾

📖 讲

每个知识点先给生活类比,再落到代码,让你看得到"为什么"。

💻 练

每个知识点后紧跟在线可运行习题,写完立刻按 Ctrl + Enter 运行。

🎯 测

穿插即时选择题与综合案例,最后一题是把整章串起来的小项目。

课堂约定:看到 ✎ 动手实验室 的页面,请暂停 2 分钟自己敲一遍——看懂和敲出来是两回事。
开场 · PROBLEM

一个真实的问题:50 个同学的成绩怎么存?

❌ 第 1 章的写法(50 个变量)

笨办法

变量爆炸、无法循环、改一个名字要改 50 处。

✅ 第 2 章的写法(1 个序列)

序列办法

一个名字管住全部数据,编号、截取、排序全都有现成工具。

🔑
数据结构(data structure):把一批相关数据按某种方式组织起来的"容器"。 Python 中最基础的数据结构叫 序列(sequence) —— 里面每个元素都带一个编号。 学会它,你才真正开始"处理一批数据",而不只是"处理一个数"。
开场 · MAP

第 2 章知识地图

① 序列概述

序列 / 容器
列表 · 元组 · 字符串
可变 vs 不可变

P23

② 通用序列操作

索引 · 切片 · 相加
乘法 · 成员资格
len / min / max

P24–31

③ 列表:主力

list() · 改元素 · del
切片赋值
11 个常用方法

P31–38

④ 元组

不可修改的序列
逗号的魔力
列表与元组对照

P38–39
一张图看懂全章关系
序列 Sequence
◂ ▸
字符串 str(不可变)
元组 tuple(不可变)
列表 list(可变 ✔ 本章主角)
通用操作
索引 / 切片 / + / * / in
三种序列都能用
💡
字符串你已经在第 1 章见过,它也是一种序列——所以本章学的操作,字符串同样适用。这就是"通用"二字的含义。
开场 · GOALS

下课前,你应该能做到这些

1 说得出

准确说出序列、索引、切片的含义,解释为什么索引从 0 开始、为什么切片"顾头不顾尾"。

2 写得对

熟练使用 [i][a:b][a:b:step]+*in 处理列表、元组与字符串。

3 用得活

会用 append / insert / pop / remove / sort / sorted / index 等方法管理一个真实列表。

4 避得开坑

知道 y = x.sort() 为什么得到 None,知道 b = ab = a.copy() 的天壤之别。

5 分得清

清楚列表与元组的区别,能用 tuple 表达"不允许修改"的数据(如坐标、RGB 颜色)。

6 做得完

独立完成"班级成绩管理"小项目:录入、查分、排名、统计、榜单输出。

MODULE 01 · 2.1

序列概述

在 Python 里,最基本的数据结构是序列。序列中的每个元素都有编号——这个编号,我们叫它"索引"。

数据结构与容器列表 / 元组 / 字符串可变 vs 不可变嵌套序列
01
2.1 · 序列概述

什么是序列sequence

📦 数据结构

以某种方式(如编号)组合起来的数据元素集合。元素可以是数、字符,甚至是另一个数据结构。

🔢 序列

Python 中最基本的数据结构。每个元素都带编号:第一个元素索引为 0,第二个为 1,依此类推。

🗄️ 容器 container

可包含其他对象的对象。两大类:序列(元素有编号,如列表)与映射(元素有名字/键,如字典,第 4 章)。集合 set 是第三类。

一个列表长什么样 —— 班级前 5 名
🧭
记法:索引不是"第几个",而是"离起点有多远"——偏移量。第 1 个元素离起点 0 步,所以是 0。这一点后面会专门讲。
2.1 · 生活类比

把序列想成一整排快递柜

快递柜 / 储物柜
柜子从 0 号开始数
不是从 1 号——这是 Python 的规矩
-1 号是最后一个
从右往左数,不用知道总长

🏫 类比 1:班级座位表

一列为一组,row[0] 是第一排。座位不动,人可换 → 列表。

📅 类比 2:课程表

周一到周五是 5 个元素,timetable[2] 是周三的课。

🪪 类比 3:身份证号

字符串也是序列!idcard[6:14] 直接切出出生日期。

🤔
想一想:如果柜子从 1 号开始编号,那么"倒数第 1 个"该写成什么?Python 选择从 0 开始,正是为了让负索引能优雅地绕到末尾。
2.1 · 序列家族

Python 内置的三种常用序列

列表 list

方括号 [ ]可变 —— 随时增删改。
本章主角,Python 的"主力"。

元组 tuple

圆括号 ( )不可变 —— 一旦创建不能改。
适合放"不许改"的数据。

字符串 str

引号。不可变 —— 字符的序列。
第 3 章详细讲,本章操作对它全适用。

三者都支持下面这套"通用操作"(本章 2.2 节)
seq[i]
索引
seq[a:b]
切片
seq1+seq2
相加
seq*n / x in seq
乘法 / 成员
📌
本章重点讨论 列表元组;字符串的详细方法在第 3 章。但请记住:通用操作对三者一视同仁
2.1 · 核心差异

列表与元组,只差一个字:能不能改

📓 列表 = 活页本 可变 mutable

可以随时插入新页、撕掉旧页、涂改某一页。适用于中途需要添加元素的场景。

📕 元组 = 印刷好的书 不可变 immutable

印出来就定型了,改不动。适用于出于某种考虑必须禁止修改的场景。

❓ 为什么还要有元组?

① 元组可作字典的键,列表不行(第 4 章);
② 有些内置函数/方法返回的就是元组,你躲不开;
③ 表达"这组值不该被改"的设计意图

🔁 什么时候可以互换?

自己写程序时,几乎总能用列表代替元组。唯一硬限制:当元组被当作字典键或集合成员时,不能换。

⚠️
别混淆:"不能改"指的是元素本身不能被替换。如果元组里装了一个列表,那个列表内部仍然可以改(选讲,了解即可)。
2.1 · 上手

动手:创建你的第一个列表

在 IDLE / 下方实验室里逐行试
ming = ['张伟', 17, '男']

✨ 列表的三个特点

  • 元素放在方括号里,逗号分隔
  • 元素类型可以不同(字符串、整数混着装)
  • 元素有先后顺序,顺序就是信息
✎ 试一试 · 创建列表Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
列表里可以同时放字符串和数字;len() 数出元素个数;ming[-1] 直接取最后一个。
2.1 · 进阶

列表里装列表:班级花名册

书本示例(P23)· 数据库雏形
🔗
两次索引 database[1][0]:先取出第 2 个人,再取他的姓名。
换成我们班:roster = [[姓名, 年龄], ...]
17 · 男
17 · 女
18 · 男
练习 · EXERCISE 1

✎ 练习 1:建一份小组名单并取元素

已知 group = ['赵一','钱二','孙三','周五']group[2] 的结果是?
提示:画出来就不容易错
✎ 动手实验室 · 练习 1Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
第 2 题先留 guess = 0 让程序能跑起来(会输出"赵一"),再把它改成 -1。 第 4 步改的是列表自身,不需要重新赋值——这正是"可变"的含义。
MODULE 02 · 2.2

通用的序列操作

索引、切片、相加、相乘、成员资格检查 —— 这五件事对列表、元组、字符串全都通用。学会一次,三处受益。

索引 indexing切片 slicing相加 +乘法 *成员 inlen / min / max
02
2.2 · 总览

五种通用操作,一张表先记住

操作写法含义生活类比
索引seq[i]第 i+1 个元素报学号,叫一个人起来答题
切片seq[a:b]a 到 b-1 这一段点名"第 2 排到第 5 排"
相加seq1 + seq2两个序列起来(同类型)两个班合并成一个大名单
乘法seq * n把序列重复 n 次复印 30 份同样的试卷
成员资格x in seq判断 x 在不在里面 → True/False查名单上有没有这个人

🔧 外加三个内置函数

len(seq) 元素个数
max(seq) 最大元素
min(seq) 最小元素

🎯 贯穿全章的主线

所有操作都围绕"编号"展开。把编号想明白,切片和步长自然就通了。

⏭ 本章不讲迭代

对序列逐个处理叫迭代(for 循环),将在 5.5 节详细讲。今天先手动取。

📖
书上说的"通用":指这些操作不挑类型——列表能做,元组能做,字符串也能做。这是 Python 设计优雅的地方。
2.2.1 · 索引

索引:编号从 0 开始indexing

greeting = 'Hello' —— 字符串也是序列,每个字符一个索引
交互式演示

📌 要点 1:字符就是长度 1 的字符串

Python 没有专门的"字符类型"。greeting[0] 得到的 'H' 是字符串。

📌 要点 2:字面量也能直接索引

'Hello'[1] 与先赋值给变量再索引效果完全一样。

📌 要点 3:函数返回值也能直接索引

input('Year: ')[3] —— 拿到输入的第 4 位,一步到位。

⚠️
全班最常犯的错:想把第 3 个元素取出来,写成 seq[3] —— 那其实是第 4 个。第 3 个是 seq[2]
2.2.1 · 原理

为什么是 0?因为它是偏移量

把索引看成"从起点走了几步"
起点
0 步
1 步
2 步
3 步

索引描述的不是"第几个",而是"离开头多远"。第一个元素就在开头,距离为 0。 这样定义后,切片的长度可以直接用 b - a 算出来——这是数学上的美感。

🧮 顺带解决一个问题

若从 1 开始编号,seq[1:3] 里到底有 2 个还是 3 个元素?
从 0 开始 + 顾头不顾尾:元素个数 = 尾 - 头,永远成立。

🌍 不是 Python 独有

C、Java、JavaScript 等主流语言都从 0 开始。早适应早受益。

🎵 记忆口诀

"第 n 个,索引 n-1"

🗣️
课堂提问:一个列表长 10,最后一个元素的正索引是几?(答案:9) 那它的负索引呢?(答案:-1)
2.2.1 · 负索引

负索引:-1 就是最后一个

scores = [98, 95, 93, 90, 88] —— 正数从左往右,负数从右往左
对比两种写法
💡
负索引的绝对值不能超过长度。长度 5 的列表,最小只能到 -5

🎯 什么时候用负索引?

当你不知道列表有多长,却想拿最后几个元素时。比如"最新一次月考成绩"。

🔁 正/负索引换算

长度为 n 的序列,负索引 -k 等价于正索引 n - k
例:n=5,-23

⚠️
注意:负索引不是"倒着存的另一份数据",它只是 Python 提供的一种数法——同一个元素,两种叫法。
2.2.1 · 易错点

踩坑现场:IndexError 索引越界

❌ 越界访问

只有 3 个人(索引 0/1/2),却去要第 4 个。Python 立刻报错,不会给你 None

✅ 安全写法

合法索引范围一览(长度 n=3)
正向
0 ~ n-1
负向
-n ~ -1
越界
≥ n 或 < -n
a = [10, 20, 30, 40],下面哪个写法不会报错?
🧑‍🏫
老师提示:看到 IndexError 先检查两件事——① 列表是不是空的;② 索引是不是比"长度-1"大了。
代码清单 2-1 · P25

案例:把 2026-9-20 变成 September 20th, 2026

书本原码(简化注释版)

▶ 运行结果

🔍 代码精读:两个 -1

  • months[month-1]:月份输 8,但 8 月存在索引 7,必须减 1
  • endings[day-1]:同理,16 日对应索引 15
  • endings加法与乘法拼出 31 个后缀:1st 2nd 3rd 4th…20th 21st…
🔁
改成中国用法:months 换成 ['一月','二月',…],删掉 endings,输出 print(month_name + str(day) + '日') —— 这就是教材里的"日期格式化"。
2.2.2 · 生活应用

索引能干啥?拆手机号、拆身份证

phone = '13812345678'(11 位)
idcard = '11010520060915001X'(18 位)
实用代码
🧠
为什么这样切?身份证第 7~14 位是出生日期(共 8 位),起点索引是 6(第 7 位),终点索引是 14(第 15 位,不包含)。 正是"顾头不顾尾"让 14-6=8 恰好等于要取的位数。
练习 · EXERCISE 2

✎ 练习 2:用索引拆解数据

已知数据
要取出数学成绩 88,应该怎么写?
✎ 动手实验室 · 练习 2Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
stu[-1] 先拿到最内层列表 ['数学',88],再 [1] 拿分数。嵌套结构就是"一层一层拆"。
2.2.2 · 切片

切片:两个索引,取走一整段slicing

numbers = [1,2,3,4,5,6,7,8,9,10] → numbers[3:6]
语法与示例

📐 语法 seq[起点 : 终点]

冒号分隔两个索引。结果是同类型的新序列:列表切片还是列表,字符串切片还是字符串。

🎯 为什么 numbers[3:6] 是 3 个元素?

因为 6 - 3 = 3。终点索引的元素不在结果里,个数刚好等于"终点 - 起点"。

🧩 负数也能当边界

tag[32:-4]:从索引 32 一直取到倒数第 4 个之前

⚠️
切片不会越界报错!numbers[7:100] 只会把后面能给的都给你。这与单个索引 numbers[100] 报错形成鲜明对比。
2.2.2 · 核心规则

切片的铁律:顾头不顾尾

seq[a:b] —— 包含 a,不包含 b(半开区间 [a, b) )
A
0
B
1
C
2
D
3
E
4
seq[0:3]['A','B','C'] (含 0,不含 3,共 3-0=3 个)

✅ 好处 1:个数一眼看出

seq[a:b] 的元素个数 = b - a
想取 5 个,就写 seq[i:i+5]

✅ 好处 2:相邻切片无缝拼接

seq[:3] + seq[3:] 恰好等于原序列,不重不漏

✅ 好处 3:空切片能表达位置

seq[2:2] 是空序列,它标出了"第 2 个元素前面"这个插入点

s = 'Hello world's[2:7] 的结果是?
2.2.2 · 简写

绝妙的简写:留空就是"到头 / 到尾"

numbers = [1,2,3,4,5,6,7,8,9,10]

📋 简写速记

写法等价
seq[a:]从 a 一直到末尾
seq[:b]开头一直到 b-1
seq[:]整个序列(复制)

⚠️ 为什么 [-3:-1] 拿不到 10?

因为 -1 就是 10 所在位置,而终点不包含。想包含最后一个,要么写 [-3:],要么理解:负索引做终点时同样"顾头不顾尾"

💾 seq[:] 的妙用

这是复制列表最简洁的写法之一(另一种见 copy(),2.3.3 节)。

🧠
口诀:"起点省略从头起,终点省略到末尾;两个都省整份抄。"
2.2.2 · 步长

第三个参数:步长 step

numbers[0:10:2] —— 每 2 个取 1 个(隔一个跳一个)
完整语法 seq[起点 : 终点 : 步长]

🎯 步长的含义

默认步长是 1(一个挨一个取)。步长为 n 表示"每隔 n-1 个取一个"。

🎵 生活类比:抽查

全班 40 人按学号站好,"每隔 4 个抽 1 个"点名 → 步长 4,抽中学号 1、5、9…

⚠️ 步长不能为 0

numbers[::0] 会报 ValueError: slice step cannot be zero —— 原地不动没法前进。

💡
实用场景:取奇数位 / 偶数位元素 —— seq[::2](第 1、3、5…个)、seq[1::2](第 2、4、6…个)。
2.2.2 · 负步长

步长为负:倒着走,顺便学会反转

numbers = [1,2,3,4,5,6,7,8,9,10]

🧭 负步长的两条规矩

  • 起点必须大于终点(从左往右的索引值比较)
  • 依然顾头不顾尾:含起点,不含终点

⭐ 王牌写法:seq[::-1]

把序列倒过来!这是本章最值得背下来的一行代码。

🔍 如何判断是不是回文?

s == s[::-1] —— 一句话判断"上海海上""level"是不是回文串。

🧠
为什么 [::-1] 能反转?起点和终点都省略时,Python 会按步长方向自动决定:正步长从头走到尾,负步长从尾走到头
代码清单 2-2 · P27

案例:从网址里切出域名

url = 'http://www.python.org' —— 数一数每个字符的位置
程序代码

🔍 数字从哪来?

  • 'http://www.'11 个字符 → 域名从索引 11 开始
  • '.org'4 个字符 → 终点用 -4,正好停在 g 之前

🤔 这个程序的局限

它假设网址一定是 http://www.xxx.com 这种格式。
遇到 https://.cn 就失效了。
这不怪你,书上的例子只是演示切片。

🚀 改进思路(学完第 3 章可做)

split('.')find('//') 定位,就不再依赖写死的数字了。

🗣️
课堂讨论:如果输入 https://www.baidu.comurl[11:-4] 会切出什么?(答案:'ww.baidu' —— 所以死数字不可靠)
2.2.2 · 速查

切片速查表(建议截图保存)

写法结果(以 s='Python' 为例)
s[0]'P' 取 1 个
s[1:4]'yth' 取索引 1~3
s[:2]'Py' 从头到索引 1
s[4:]'on' 从索引 4 到末尾
s[-1]'n' 最后一个
s[-3:]'hon' 最后三个
写法结果
s[:]'Python' 完整复制
s[::2]'Pto' 隔一个取一个
s[::-1]'nohtyP' 反转
s[::-2]'nhy' 倒着隔一个取
s[10:20]'' 越界也不报错
s[2:2]'' 空切片=插入点
🎯
一句话总结切片:seq[起点 : 终点 : 步长]含头不含尾,步长控制方向与间隔;三者都可省略。
⚠️
常错点对照:s[-3:-1] 只有 2 个元素,不是 3 个;想要"最后 3 个"请写 s[-3:]
练习 · EXERCISE 3

✎ 练习 3:切片四连击

已知
sc[1:4] 有几个元素?
✎ 动手实验室 · 练习 3Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
第 5 题:'信息技术' 各占 1 个索引(中文一个字一个字符),所以 s[4:] 正好是 'Python'
2.2.3 · 相加

序列相加:用 + 把两个名单拼起来

[1,2,3] + [4,5,6] → 一条更长的队伍
1
2
3
+
4
5
6
=
1
2
3
4
5
6
代码演示

⚠️ 不同类型不能相加

虽然都是序列,但列表 + 字符串 不被允许。一般规则:只能拼接同类型的序列

🧩 生活类比

1 班名单 + 2 班名单 = 年级名单(同类型可拼)。
名单 + 一个分数 = ❌ 拼不起来(类型不同)。

💡
想跨类型怎么办?先转换:[1,2,3] + list('abc')str([1,2,3]) + 'abc'list() 见 2.3.1 节)。
2.2.4 · 乘法

序列乘法:复制 N 份 与"占位"技巧

乘法 = 重复

🎨 妙用:画表格线

教材里常见的 print('-' * 40) 就是字符串乘法的典型场景。

🕳️ 空列表与 None

None 表示"什么都没有"。要预留 10 个位置但暂时没内容,就用 [None]*10

📝 典型用法:成绩表初始化

⚠️
注意:[0]*10 创建的是 10 个 0;[None]*10 创建的是 10 个"空位"。语义不同:0 是一个值,None 表示没有值
代码清单 2-3 · P29

案例:把一句话装进居中的方框

综合运用:len() + 乘法 + 加法

▶ 运行效果

🔍 三个关键计算

  • text_width = len(sentence) 量出句子长度
  • box_width = text_width + 6 左右各留 3 格
  • left_margin = (80 - box_width)//2 居中(// 是整除)

✏️ 改造任务(课后)

把边框字符改成 '★',或用 '=',做出你自己风格的"成绩单标题框"。

🧠
核心思想:Python 里"画图形"靠的就是字符串乘法 —— 想要 30 个横线,不用循环,直接 '-' * 30
练习 · EXERCISE 4

✎ 练习 4:拼接与重复

下面哪句会报错

🎯 本练习目标

  • + 合并两个班级的名单
  • * 生成分隔线与占位列表
  • 理解 None 的"占位"含义
✎ 动手实验室 · 练习 4Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
第 4 题用了 row[:] 复制——如果直接写 [row]*3,三行会是同一个列表,改一个全变(这就是后面要讲的引用陷阱)。
2.2.5 · 成员资格

成员资格:x in seq 在不在里面?

返回 True / False —— 布尔值

✅ in 是什么?

一个布尔运算符:检查结果并返回 True(真)或 False(假)。这类值叫布尔值,将在 5.4 节详讲。

🔤 对字符串的特殊之处

一般 in 判断"是不是其中一个元素"。但字符串的元素是字符,所以:
'P' in 'Python' → True(检查字符)
'yth' in 'Python' → True(还能查子串

🚫 反过来写:not in

'x' not in permissions → True,表示"不在里面"。

🏫
生活类比:老师拿着点名册问"张伟在不在?"—— '张伟' in 点名册。在 → True,不在 → False。垃圾邮件过滤也用这招:含 '$$$' 就判为广告。
代码清单 2-4 · P30

案例:用 in 做一个登录验证

数据库就是一个"列表的列表"

🔍 为什么一个 in 就够了?

database 的每个元素是一个 [用户名, PIN] 小列表。把用户输入也拼成同样的小列表,in 就能整条比对

结构示意
['albert','1234']
['dilbert','4242']
['smith','7524']
['jones','9843']

['albert','1234'] in database → True

🛡️ 现实提醒

真实系统绝不会这样存密码(要加密存储)。这里只是演示 in 的用法。

🚀
升级任务:加上 else: print('Access denied'),让它拒绝错误密码(if/else 第 5 章正式学)。
2.2 · 内置三剑客

len / min / max:长度、最小、最大

📏 len(seq)

返回序列元素个数

中文一个字算 1 个字符。

⬇️ min(seq)

返回最小的元素。

字符串按字典序比大小。

⬆️ max(seq)

返回最大的元素。

大写字母比小写"小"(ASCII 码)。

🎁 它们还能直接吃散装参数

max(2, 3)min(9, 3, 2, 5) —— 不传序列,直接把数一个个丢进去也行。

🏫 课堂实战:成绩单统计

⚠️
min/max 不能混类型:max([1, 'a']) 会报 TypeError——数字和字符串没法比大小。
练习 · EXERCISE 5

✎ 练习 5:查名单 + 成绩统计

'yth' in 'Python' 的结果是?

📊 综合小任务

已知全年级成绩列表,请:① 判断某人是否缺考(不在名单中);② 输出人数、最高分、最低分、平均分。

✎ 动手实验室 · 练习 5Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
第 3、4 题涉及 for 循环与 sorted(),属于"提前尝鲜"——正式内容在第 5 章与 2.3.3 节。
MODULE 03 · 2.3

列表:Python 的主力

列表不只是"能装东西"——它可以被修改。改元素、删元素、给切片赋值,外加 11 个趁手的方法,这才是真正的生产力。

list()改 / 删切片赋值append · insert · popsort · sorted引用陷阱
03
2.3.1 · list()

list():把别的东西变成列表

为什么需要它?
🔑
字符串不可修改,想一个字一个字地改,就先用 list() 拆成列表,改完再用 join() 拼回去。

🔁 反向操作:''.join(列表)

join 的详细用法在第 3 章(3.4.3 节)。今天先记住这句"咒语"。

💡 list 的参数可以是任何序列

不只是字符串——元组、range、甚至另一个列表都行。

🧪 小实验:拆名字

📌
补一句:严格来说 list 是一个"类"(类型),不是普通函数。现阶段你把它当函数用完全没问题,第 9 章会解释差别。
2.3.2 · 修改

改元素:x[1] = 2 就够了

x = [1, 1, 1] → x[1] = 2 → x = [1, 2, 1]
代码演示

✅ 这就是"可变"

不需要 x = x[1]=2 这种写法,也不用重新赋值整个列表——列表自己在原地被改了

⚠️ 不能给不存在的元素赋值

长度只有 2,就不能改索引 100。要能改,得先让列表长到至少 101 —— 用 [None]*101 初始化。

🧠
对比记忆:字符串不能这样改 —— s = 'Hello'; s[0] = 'J' 会报 TypeError。这正是列表与字符串的分水岭。
2.3.2 · 删除

删元素:del 语句

names = ['Alice','Beth','Cecil','Dee-Dee','Earl'] → del names[2]
Alice
Beth
Cecil
Dee-Dee
Earl
删除后:['Alice', 'Beth', 'Dee-Dee', 'Earl'] 长度 5 → 4
代码演示

⚠️ 长度真的会变短

删除后后面的元素全部前移,索引会重新编号。这和"赋值为 None"完全不同。

🔧 del 不只是删列表元素

还能删字典元素(第 4 章)、删变量本身(第 5 章)。它是 Python 的一条通用语句。

🆚 del vs pop vs remove

del位置删且不给回东西;pop 按位置删并返回remove删。后面细讲。

🏫
生活类比:花名册上划掉一个转学生,后面所有人的"第几位"都会往前挪一格。
2.3.2 · 切片赋值

切片赋值:替换 · 插入 · 删除 一招三式

① 等长替换

一次给多个元素赋值。

② 不等长替换

切片可以换成长度不同的序列 → 列表会伸长/缩短。

③ 插入(替换空切片)

[1:1] 是空切片 = 插入点。

④ 反向:用空列表删除一段

给切片赋一个空列表,就是删除这一段。

🎯 为什么这招强大?

  • 不用循环就能批量改一片元素
  • 长度可伸缩,插入/删除一体完成
  • 是理解列表"可变性"的最佳例子

代价:可读性一般,日常更推荐 insert/remove

🧠
口诀:"给切片赋什么,那一片就变成什么。" 赋空 → 删除;赋更长 → 伸长;赋等长 → 替换。
2.3.3 · 方法

列表方法全家福(11 个)

📖 什么是方法?

方法是与对象(列表、字符串等)绑定在一起的函数。调用格式:对象.方法(参数) —— 比函数调用前面多了"对象 + 一个点"。第 7 章讲清楚它到底是什么。

方法改列表?作用
append(x)✅ 就地把 x 加到末尾
clear()✅ 就地清空整个列表
copy()返回列表的副本
count(x)统计 x 出现次数
extend(seq)✅ 就地把另一个序列逐个追加到末尾
index(x)查 x 第一次出现的位置
方法改列表?作用
insert(i, x)✅ 就地位置 i 插入 x
pop([i])✅ 就地删除并返回值(默认最后一个)
remove(x)✅ 就地删除第一个等于 x 的元素
reverse()✅ 就地反转列表元素顺序
sort()✅ 就地排序(可加 key / reverse)
另:sorted(seq)内置函数不是方法,返回新列表,不改原列表。
⚠️
最重要的提醒:带 ✅ 的方法大多就地修改且不返回值(返回 None)。写 y = x.append(1) 会得到 None——这是新手第一大坑。
2.3.3 · 增

三兄弟:append · extend · insert

append(x) 加在末尾

把 x 当作一个整体加进去。

extend(seq) 逐个并入

把序列拆开一个一个加。

insert(i, x) 插队

插到索引 i 之前。

🔥 经典混淆:append 一个列表会怎样?

🆚 extend vs 拼接 +

extend 效率更高(不用造副本);+ 不改原列表。

💡
命名小建议:别把列表命名为 list(会挡住内置函数),用 scoresprice_list 这种有信息量的名字。
2.3.3 · 删

pop:拿走一个,还能接着用

pop 是唯一"既改列表又返回值"的方法

🎯 典型场景:撤销/回退

浏览器的"后退"、编辑器的 Ctrl+Z,本质都是从一个历史栈里 pop 出上一个状态。

🥞 栈 Stack:后进先出 LIFO

第1个放的
第2个
第3个(最后)

像一叠餐盘:只能从顶部放(append)和取(pop)。
最后放上去的,最先被取走。

📌
想做"先进先出"的队列?insert(0, x)pop(),或 append()pop(0)。更好的方案是 collections.deque(第 10 章)。
2.3.3 · 删与翻转

remove · clear · reverse

remove(x) 按值删除

只删第一个匹配的元素;找不到就报错;不返回值

clear() 清空

注意:是清空内容,列表对象还在(长度变 0)。

reverse() 反转

reverse() 就地改;reversed() 返回迭代器不改原列表,需 list() 转换。

🆚 remove vs del vs pop

写法依据返回值
del x[2]位置
x.pop(2)位置(被删元素)
x.remove('be')

✅ 安全删除的写法

⚠️
别写 x = x.remove('be')x = x.reverse() —— 它们返回 None,会把你的列表变成 None
2.3.3 · 查

index · count:查位置、数个数

index(x) —— 找第一次出现的位置
⚠️
找不到会报错(不像字符串的 find 返回 -1)。稳妥做法:先 if x in lst:index
count(x) —— 数出现次数

🔍 count 只数"表面一层"

上面 x.count(1) 得 2 —— 嵌套在 [1,2] 里的 1 不参与计数

🏫
课堂小练:scores = [100, 92, 100, 88, 100] 中有几个满分?(答案:scores.count(100) → 3) 第一次满分出现在第几位?(答案:scores.index(100) → 0)
2.3.3 · 排序

⚠️ 全章第一大坑:y = x.sort()

❌ 错误写法(几乎人人都踩过)

sort() 就地修改 x(变成 [1,2,4,6,7,9]),但不返回值——y 拿到 None

✅ 正确写法:用 sorted()(推荐)

想留原列表又用 sort()?先 y = x.copy() 再排。注意 y = x 不行——只是同一个列表的两个名字。

🧠
口诀:sort() —— 方法,改自己,返回 None;sorted() —— 函数,不动原数据,返回新列表。(Python 2.3+ 为稳定排序
x=[3,1,2]; y=x.sort() 之后,xy 分别是?
2.3.3 · 高级排序

高级排序:keyreverse

sort(key=..., reverse=...)

🔑 key 是什么?

你给一个函数,Python 用它给每个元素算出一个"排序键",再按排。
例:key=len → 按长度;key=abs → 按绝对值。

↕️ reverse 是什么?

True 表示降序(从大到小);默认 False 是升序。
它俩都叫关键字参数,第 6 章细讲。

🏫 实战:成绩排名

📚
拓展:想深入排序可阅读官方 HOWTO《Sorting Mini-HOW TO》(wiki.python.org/moin/HowTo/Sorting)。自定义 key 函数在第 6 章学完函数后威力更大。
2.3.3 · 第二大坑

⚠️ 第二大坑:b = a 不是复制!

❌ b = a:两个名字,同一个列表

a
b
1
4
3

✅ b = a.copy():真正的两份

a
b
1
2
3

🔁 三种等价的复制写法

b = a.copy() | b = a[:] | b = list(a)
效果完全相同,挑一个你顺眼的用。

🧠 为什么会这样?

变量名字只是标签,贴在同一个盒子上。b = a 是给盒子又贴了一张标签,不是造了新盒子。

a=[1,2,3]; b=a; b[0]=9,此时 a 是?
综合案例

项目:一个班级成绩管理系统

把本章知识串起来(可直接在实验室运行)

▶ 运行结果

🔍 用到了本章哪些知识?

append · index · del · sort(key=…, reverse=…) · len/max/min · count · 字符串乘法 '='*28
ziplambda 属于"超纲尝鲜",第 6 章正式学——先感受威力。

🚀 课后升级:加入 input() 现场录入成绩 · 支持按姓名查分 · 用 in 查询是否在册。

练习 · EXERCISE 6

✎ 练习 6:管理一份值日表

📋 任务清单

  1. 建立值日表 duty = ['李雷','韩梅梅','王小明']
  2. 周五要加一个人 → 用 append
  3. 王小明请假 → 用 remove 删掉
  4. 需要在第 2 位插一个同学 → 用 insert
  5. 把'韩梅梅'换成'韩梅梅(组长)' → 用 index + 索引赋值
  6. 打印最终名单与人数
要在第 2 个位置插入元素,应该写?
✎ 动手实验室 · 练习 6Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
改元素时若不知道位置,先用 index() 查;若元素可能不存在,要先 if x in duty 保护,否则会 ValueError
练习 · EXERCISE 7

✎ 练习 7:排序、复制与避坑

🎯 本题目标:亲自踩一遍两个坑

  1. 验证 y = x.sort() 得到的是 None
  2. sorted() 拿到排好序的列表,原列表不变
  3. 验证 b = a 会"连坐",b = a.copy() 不会
  4. reverse=True 排出排行榜
想"保留原列表,另得一份排好序的",最简洁的写法是?
✎ 动手实验室 · 练习 7Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
两个坑记住一次受益终身:方法 sort 改自己不返回;赋值 = 贴标签不复制
MODULE 04 · 2.4

元组:不可修改的序列

元组和列表几乎一模一样,唯一的差别是不能改。而这个"不能改",恰恰让它有了独特的价值。

创建元组逗号的魔力tuple()为什么需要元组与列表对照
04
2.4 · 创建

创建元组:逗号才是关键

三种创建方式

⚠️ 单元素元组的坑

🔑 口诀:括号可以省,逗号不能省

决定"这是不是元组"的是逗号,不是圆括号。(42)42 完全等效。

🏫 生活类比:坐标与颜色

这些"一组固定搭配的值",天生就该用元组。

🤔 为什么要加圆括号?

主要是为了可读性和避免歧义(比如函数参数里)。语法上常常可省。

⚠️
考试高频:type((42))<class 'int'>type((42,))<class 'tuple'>。就差一个逗号。
2.4 · 转换

tuple() 转换 · 元组的常规操作

tuple(seq):把序列变成元组

🔁 与 list() 是一对

list()tuple() 可以来回转换。想改元组内容?先 list() 转成列表,改完再 tuple() 转回去。

✅ 元组做的事

索引、切片、相加、乘法、成员、len/min/max —— 全都支持

❌ 元组不能做的事

没有 appendinsertpopremovesort
也不能 x[0] = 9 改元素。只有 indexcount 两个方法。

🧠
切片也是元组:元组的切片结果仍是元组,正如列表的切片仍是列表。类型保持一致
2.4 · 价值

既然不能改,为什么还要元组?

① 可以当字典的键 最重要

字典(第 4 章)的键必须不可变。列表不行,元组可以。
典型:用 (经度, 纬度) 作键查城市。

② 有些函数返回的就是元组

Python 内置的很多函数/方法返回元组,你躲不开,只能跟它打交道。

③ 表达"不许改"的设计意图

看到元组,读代码的人就知道:这组值是固定的,别去动它。这是一种自我说明的代码风格。

④ 略微更快、更安全

不可变对象在实现上可以更紧凑;也避免了被误改导致的隐蔽 bug。

🎯
实用建议:一般需求用列表就够了。只有当你明确需要"不可变"(尤其要当字典键)时,才用元组。
判断标准:这组值的长度和含义固定(如坐标 x,y、日期 年,月,日)→ 元组;会增减变化(如名单、成绩表)→ 列表。
2.4 · 对照

列表 vs 元组:一张表彻底分清

对比项列表 list元组 tuple
写法[1, 2, 3] 方括号(1, 2, 3) 圆括号(可省)
可变性可变,可增删改不可变,创建即定型
单元素写法[42] 直接写(42,) 必须带逗号
可用方法丰富:append / insert / pop / remove / sort / reverse …只有 indexcount
通用操作完全相同:索引 · 切片 · + · * · in · len/max/min · sorted()
能否当字典键❌ 不行✅ 可以(第 4 章)
相互转换tuple(列表) → 元组list(元组) → 列表
典型场景班级名单、成绩表、待办清单(会变)坐标、RGB 颜色、日期、配置(固定)

✅ 选择决策树

① 需要增删改吗?要 → 列表
② 要当字典键 / 集合成员吗?要 → 元组
③ 都不确定 → 用列表(更灵活)

🧪 一句话验证

拿到一个序列不知道是列表还是元组?
type(x) 一查便知:
<class 'list'> / <class 'tuple'>

练习 · EXERCISE 8

✎ 练习 8:元组与类型转换

type((42))type((42,)) 分别是?

📋 任务

  1. 创建 3 种元组:普通、空、单元素
  2. tuple() 把字符串和列表转成元组
  3. 试试修改元组元素,观察报错信息
  4. 把元组转回列表再修改,体会"绕道"的方法
✎ 动手实验室 · 练习 8Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
第 3 步取消注释后会看到:TypeError: 'tuple' object does not support item assignment —— 这就是"不可变"的直接证据。
2.5 · 小结

本章小结:一张图装下整章

第 2 章 · 序列
列表 list
可变 · 方括号
11 个方法
本章主力
元组 tuple
不可变 · 圆括号
逗号是关键
可作字典键
字符串 str
不可变 · 引号
字符的序列
第 3 章详讲
│ 三者共用
索引 [i]
切片 [a:b:step]
相加 +
乘法 *
成员 in
len / min / max
sorted()
两个必记坑:y = x.sort() 得到 None(用 sorted()) · b = a 不是复制(用 a.copy()a[:]
2.5.1 · 速查

本章出现的新函数 / 方法

内置函数(2.5.1 小节原表)
函数描述
len(seq)返回序列包含的元素个数
list(seq)把序列转换为列表
max(args)返回序列或一组参数中的最大值
min(args)返回序列或一组参数中的最小值
reversed(seq)反向迭代序列(返回迭代器,需 list() 转换)
sorted(seq)返回一个有序的新列表,原序列不变
tuple(seq)把序列转换为元组
常用列表方法(2.3.3 小节)
方法描述
append(x)末尾追加一个元素
clear()清空列表内容
copy()返回列表副本
count(x)统计 x 出现次数
extend(seq)用另一序列扩展列表
index(x)查 x 首次出现的位置
insert(i, x)在位置 i 插入 x
pop([i])删除并返回元素(默认末尾)
remove(x)删除第一个值为 x 的元素
reverse()就地反转顺序
sort([key][reverse])就地排序,可指定键与升降序
📌
判断标准:len()sorted() 这种括号里放对象的是函数;x.append() 这种对象在前、点号连接的是方法。
挑战 · FINAL PROJECT

🎯 综合挑战:运动会成绩统计器

📝 任务描述

校运会高一(3)班有 8 名同学参加 100 米跑,成绩(秒)如下。请编写程序完成统计。

✅ 要求(逐项完成)

  1. 输出参赛人数
  2. 输出最快(最小值)与最慢(最大值)
  3. 输出平均成绩(保留 2 位小数)
  4. 找出跑进 13 秒的同学有几人
  5. 12.8 出现了几次?(count
  6. 把成绩从快到慢排序并输出前 3 名

🏆 加分项:把"姓名+成绩"配对后排序,输出前三名的姓名和成绩(参考 P52 的 zip 写法)。

✎ 动手实验室 · 综合挑战Ctrl + Enter 运行
点击「运行」查看结果…
参考输出
要点:sorted(times)[:3] 把"排序 + 切片"连起来用;zip(times, names) 把成绩和姓名绑在一起再排序。
注意并列:12.8 秒有两人,排序时成绩相同会再比姓名,所以季军可能是郑八也可能是韩梅梅(取决于比较规则)——这正是"稳定排序"值得讨论的地方。
THE END · 2.5.2 预告

熟悉了序列,接下来是字符串

字符串也是一种序列,但它拥有的方法远比本章介绍的丰富。下一章我们将系统学习:如何设置格式、如何查找替换、如何拆分与合并。

3.1 字符串基本操作3.2 设置格式(精简版)3.3 设置格式(完整版)3.4 字符串方法
课后作业
① 复习本章 8 个练习
② 完成"运动会统计器"加分项
③ 预习第 3 章 3.1 节
本节课要点回顾
索引从 0 · 切片顾头不顾尾
sort 返回 None · b=a 不是复制
元组靠逗号
谢谢大家 · 有问题随时提问 🙌
1 / 64 ← → 翻页 · Ctrl+Enter 运行代码 · M 目录 · F 全屏

课件目录(点击跳转)