6.1 数据类型进阶——列表¶
内容梗概¶
本课是"数据类型进阶"系列的第一部分,系统讲解列表(list)的进阶操作。老师将列表操作分为四大类:增加、更新、查找、其他(含删除),逐类结合交互模式和 VS Code 演示。重点强调了切片赋值(含步长切片赋值的限制)、sort() 等就地修改方法返回 None 的"坑"、insert/pop(0) 的效率问题,以及 copy 与完整切片的等价关系。最后用一个"选课名单"的综合例子把所有操作串起来演示了一遍。
知识点详解¶
列表进阶操作的四大分类(约 01:40)¶
- 增加:向列表中添加内容
- 更新:更改列表中已有的内容(与"增加"本质上都是对列表内容的变更)
- 查找:定位某个元素、判断是否包含、统计次数等
- 其他:删除、复制、弹出等
老师提醒(约 10:10):这些方法不用死记,工作多年的程序员也要查官方文档,用多了自然记住。
增加操作(约 02:23)¶
a += [新列表]:在列表末尾拼接一个新列表。a *= n:把列表内容**重复 n 次**(约 02:53),如[1,2,3] * 3得到三个 1,2,3。a.append(x)(约 04:06):在末尾追加**单个**元素;若传入列表,会把整个列表当作一个元素塞进去(产生嵌套列表)。a.extend(t)(约 04:32):把可迭代对象t中的元素**逐个**取出追加到末尾,效果等价于+=。注意t不一定是列表,任何可迭代对象(如元组)都可以(约 08:52)。a.clear()(约 04:56):清空列表(老师称此处为"超纲知识",提前使用)。a.insert(i, x)(约 05:48):在索引i处插入元素x,其后所有元素索引顺移。- 效率问题(约 08:11):在列表前部插入会让后面所有元素后移,效率较低;处理复杂/大规模任务时要注意。
更新操作(约 10:47)¶
- 切片赋值:
a[start:end] = t,把start到end的部分替换为可迭代对象t的内容(约 11:05)。右侧t同样只需可迭代,不必是列表。 - 无步长时:新内容长度**可以**与被替换区间长度不同,甚至可以是空列表(相当于删除这段元素)(约 13:04)。
- 带步长的切片赋值:
a[start:end:step] = t,两侧长度**必须完全一致**,否则报ValueError(约 13:44–16:15,演示了"attempt to assign sequence of size 4 to extended slice of size 5"错误,并强调要学会读错误信息)。带步长时也不能用空列表删除元素,要用del。 - 排序
a.sort(key=None, reverse=False)(约 17:17): - 默认按元素值从小到大排序;
reverse=True则从大到小。 - 大坑(约 18:36):
sort()就地修改**列表本身,**返回None。d = c.sort()只会让d变成None。老师称去年出过考题。 append、extend、insert、reverse等就地修改方法同样返回None(约 19:48–22:26,逐一验证)。a.reverse()(约 20:33):就地倒序,同样返回None。
查找操作(约 22:38)¶
x in a/x not in a(约 22:50):判断元素是否在列表中,可直接用作 if 条件。演示用 VS Code 判断某人是否在名单中。min(a)/max(a)(约 25:40):取最小/最大元素。a.index(x[, start[, end]])(约 25:48):返回元素x**第一次出现**的索引;可选start/end限定查找范围。- 文档中**方括号表示可选参数**(约 26:45),与命令行可选参数写法惯例一致。
- 只返回第一次出现的下标;想找所有下标目前只能配合循环(约 30:05)。
- 索引从 0 开始,给人看名次时要 +1。
a.count(x)(约 28:09):统计元素出现次数;**不能**直接指定范围,但可先切片再count。老师举例:用打卡记录count统计出勤次数。
其他操作(约 30:39)¶
a.copy()(约 30:59):返回一个**新列表**,与完整切片a[:]等价;与前面方法不同,它**有返回值**(新列表)。对副本的操作不影响原列表。b = a * n(约 32:24):把重复 n 次的结果存入新变量(与*=原地操作区分)。a.pop([i])(约 33:20):不传参数弹出末尾元素;可传索引弹出指定位置元素。pop(0)从头部取出会使后面所有元素前移,效率低,后续会讲更好的方式。a.remove(x)(约 34:55):按**值**删除,只删**第一个**匹配项(与pop按下标删除区分)。a.clear():清空列表,返回None,不取出元素。del a[i]/del a[start:end:step](约 36:17):删除指定部分;带步长的删除只能用del,不能用空列表赋值。del a(约 36:46):删除整个变量,之后引用会报NameError: name 'a' is not defined——注意它不是None,是变量本身没了。
示例与演示¶
- 交互模式演示(约 03:06 起):
a=[1,2,3]、b=[4,5,6],演示+=、*=、append(10)、append一个列表产生嵌套、clear后extend恢复等。 - 切片赋值实验(约 11:36):用列表推导式生成
a = [0..10],把 2,3,4(索引 2:5)替换为[10,11,12];替换为空列表实现批量删除。用带步长切片b[0::2]把偶数位替换为'a','b','c','d'等字符;长度不匹配时报错。 - in 判断(约 23:23):VS Code 中定义名单列表,用
if 名字 in 列表判断某人是否在名单中。 - 综合例子:选课名单(约 37:42 起,课件下方完整代码):
- 用列表推导式生成 10 个假学号(20190001 起)作为初始选课名单;
append单独新增一位,extend(range(20,30))批量新增一批(演示extend可直接接收 range);insert(0, ...)把学号全 0 的同学插到第一位;- 无步长切片替换
students[5:15]、带步长切片替换students[0:5:2]; - 加
print提示语观察"替换前/替换后"(老师明确**不推荐单步调试**,推荐用 print 观察程序执行); sort()后reverse()实现学号从大到小(指出可合并为sort(reverse=True));in判断某同学是否选上,remove移除,clear清空(与students = []效果对比),最后del students后引用报错。- 插曲(约 42:09):
print中字符串与列表不能用+拼接(类型不同),改为print传多个参数用空格分隔。
重点与难点¶
sort()等就地方法返回None:不要写d = c.sort();排序结果在c本身。- 带步长切片赋值两侧长度必须相等;无步长则不限。带步长删除必须用
del。 append(整体放入)与extend(逐个取出)的区别。insert、pop(0)会引起元素整体移动,效率低。remove按值删且只删第一个;pop按下标删;del 变量会把变量本身删掉(再引用报NameError)。copy()返回新列表(有返回值),与其他就地方法不同。- 官方文档中方括号
[start[, end]]表示可选参数。 - 建议用
print而非单步调试观察程序执行过程。
关联内容¶
- 前置知识:第 5 章序列基础(取值、切片、拼接)、列表推导式、
lambda匿名函数(讲sort(key=...)时回顾)。 - 本课提到
extend的参数可以是元组、range——分别在本章 6.2(元组与 range)详细展开;提到"从头部取元素的更好方式"留待后续课程。 - "方法 vs 函数"的概念留待后续面向对象章节讲解(约 21:01)。
- 与上周五作业及"直男表白"解码工具(字符串两两切分)呼应。