今天你 AI 赋能了吗?打开浏览器,在地址栏输入 xuefulu.ai ,按下 Enter 即可访问学府路1号!
2026年10月14日 星期三 10:40:15
常用网址: | | 学府路1号 https://xuefulu.ai | 下载 Python https://xuefulu.ai/Python.html | 下载 TRAE https://xuefulu.ai/Trae.html

一、为什么需要列表

前面学的变量,一次只能装一个值:一个分数、一个名字。但真实世界里,数据常常是一串的。

比如一个宿舍 5 个人的数学分数。最笨的写法,是起 5 个变量:

Python
s1 = 88
s2 = 92
s3 = 75
s4 = 96
s5 = 81

分数一多,变量就多到管不过来。更好的办法:用一个列表,把这一串数装进一个名字里。

Python
scores = [88, 92, 75, 96, 81]
print(scores)

输出:

输出
[88, 92, 75, 96, 81]

一个变量 scores,就装下了 5 个分数。这种「一个变量装一串数」的容器,就是列表。

Python
scores = [88, 92, 75, 96, 81]
print('一共', len(scores), '个分数')
print('最高分', max(scores))

输出:

输出
一共 5 个分数
最高分 96

列表里每个位置上的数,叫一个元素。元素可以是数字、文字,甚至混着放。

列表是 Python 里最常用的容器。以后你会反复用到它:成绩表、商品清单、逐行读文件……只要东西是一串的,就先想到列表。

课程思政|数据安全与法治素养 · 一份成绩单一份责任

列表解决的其实是个很朴素的问题:一串数怎么装。成绩单、名单、商品清单,一个变量就装下几十上百条。可这一串数背后往往是一个个具体的人,同学的分数、客户的电话,都是受保护的个人信息。能拿到,不等于可以随手转发。动手写之前先问自己:这份数据该不该存、存多久、谁有权看,这比会不会用 append 更要紧。

二、列表是「序列」家庭的一员

在正式学列表之前,先认识一个更大的概念:序列(sequence)。字符串、列表、元组、range 都属于序列——它们的共同点是:元素排成一队,每个都有自己的位置(下标),可以从 0 开始按位置取。

序列成员例子能不能改
字符串 str'abc'不能改
列表 list[1, 2, 3]能改
元组 tuple(1, 2, 3)不能改
rangerange(5)不能改

正因为是「一家人」,下面这些操作对它们全都管用(只是结果类型不同):

操作写法说明
数个数len(s)一共几个元素
按下标取一个s[0] / s[-1]第 1 个 / 最后一个
切片取一段s[1:4]取下标 1、2、3 三个
判断在不在x in s返回 True / False
拼接s1 + s2接成一个更长的
重复s * 3重复 3 遍
遍历for x in s:一个个拿出来
Python
s = 'Python'          # 字符串也是序列
print(len(s))
print(s[0], s[-1])
print(s[1:4])
print('y' in s)

输出:

Python
6
P n
yth
True

你会看到,字符串上能做的这些事,换成列表也一样能做——因为它们都是序列。这一节学一次,四类东西都能用。

把「序列」当成一个大家庭:凡是「排成一队、能按下标取」的都算序列。本篇讲列表(能改的那个),下一篇《17-元组》讲元组(不能改的那个)。

三、创建列表的三种方式

最常用的是第一种,直接写方括号。

方式一:方括号直接写

Python
list1 = [1, 2, 3, 4, 5]
print("list1:", list1)

输出:

输出
list1: [1, 2, 3, 4, 5]

方式二:用 list() 把一串东西变成列表

range() 本身不是列表,套上 list() 就能看见里面的数字:

Python
list2 = list(range(1, 6))
print("list2:", list2)

输出:

输出
list2: [1, 2, 3, 4, 5]

方式三:先建一个空列表,后面再往里加

Python
list3 = []
print("list3:", list3)

输出:

输出
list3: []

列表很自由:类型可以混着放

Python
mixed = [1, "二", 3.0, True]
print(mixed)

输出:

输出
[1, '二', 3.0, True]

还能把列表嵌在列表里,做成一个「表格」的样子:

Python
matrix = [[1, 2], [3, 4]]
print(matrix)

输出:

输出
[[1, 2], [3, 4]]
写法什么时候用例子
[1, 2, 3]已知有哪些元素,直接列出来nums = [10, 20, 30]
list(range(...))想要一串连续的数字list(range(1, 6))
[]先空着,待会儿用 append 一个一个加todo = []
方括号 [] 是列表的标志。看到方括号,就想到「一串东西」。空列表 [] 长度为 0,但它是合法的列表,随时能往里加东西。

四、索引访问(正索引、负索引、切片、越界)

想从列表里拿出某一个元素,靠索引(位置编号)。编号从 0 开始,不是从 1!

Python
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print(fruits[0])
print(fruits[1])
print(fruits[-1])
print(fruits[-2])

输出:

输出
苹果
香蕉
葡萄
橙子

记住两句话:正数从 0 往右数;负数从 -1 往左数(-1 是最后一个,-2 是倒数第二个)。

一次拿多个:切片

切片写法 [起点:终点],含起点、不含终点,像「左闭右开」的区间:

Python
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print(fruits[0:3])
print(fruits[1:-1])

输出:

输出
['苹果', '香蕉', '橙子']
['香蕉', '橙子']

第一个 [0:3] 拿第 0、1、2 个;第二个 [1:-1] 拿中间,去掉头尾。

用循环把每个都拿出来

Python
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
for x in fruits:
    print(x, end=" ")

输出:

输出
苹果 香蕉 橙子 葡萄 

越界会报错

列表只有 4 个元素(索引 0~3),去拿第 10 个就超出了范围:

Python
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print(fruits[10])

运行后会报错(逐字照抄解释器):

报错
IndexError: list index out of range
索引从 0 开始是最容易栽跟头的地方。想拿「第 3 个」,索引要写 2,不是 3。
拿不准元素有几个、索引写到几,先 print(len(列表)) 看一下长度。合法索引是 0 到 长度-1。

五、往列表里加东西(append / extend / insert)

列表最棒的一点:它能长大。三个加法各有分工。

append:在末尾加「一个」元素

Python
fruits = ['苹果', '香蕉']
fruits.append('橙子')
print(fruits)

输出:

输出
['苹果', '香蕉', '橙子']

extend:把另一个列表的每个元素都加进来

Python
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list1.extend(list2)
print(list1)

输出:

输出
[1, 2, 3, 4, 5, 6]

insert:插到指定位置

insert(位置, 元素),新元素会占住这个位置,后面的往后挪:

Python
numbers = [1, 2, 4]
numbers.insert(2, 3)
print(numbers)

输出:

输出
[1, 2, 3, 4]
方法做了什么例子结果
append(x)在末尾加一个元素 x[1,2].append(3) → [1,2,3]
extend([x,y])把 x、y 一个个加进末尾[1].extend([2,3]) → [1,2,3]
insert(i,x)插到索引 i 的位置[1,2,4].insert(2,3) → [1,2,3,4]
append 和 extend 容易混。append([4,5,6]) 是把「整个列表」当一个元素塞进去,结果变成 [1,2,3,[4,5,6]];想平铺着加,要用 extend。
如果只是往末尾加,用 append 就够了,它最简单也最常用。insert 要搬动后面所有元素,元素很多时会慢一点。

课程思政|工匠精神与严谨求实 · 加一个还是加一批

append 和 extend 只差几个字母,效果却差很远:一个把整个列表当成单个元素塞进去,另一个才是一个一个加进来。调程序时最费时间的,往往就是这种「看着差不多」的地方。别凭感觉猜,运行一遍看结果——打印出来对一眼,比在心里推十遍都靠谱。工程上的可靠,就是这么一次次核对攒起来的。

六、从列表里删东西(remove / pop / clear / del)

有加就有删。四种删法,删的对象不一样。

remove:按「内容」删第一个匹配的

Python
animals = ['dog', 'cat', 'bird']
animals.remove('cat')
print(animals)

输出:

输出
['dog', 'bird']

pop:按「位置」删,还会把删掉的元素还给你

Python
colors = ['red', 'green', 'blue']
popped = colors.pop(1)
print("被删掉的是:", popped)
print(colors)

输出:

输出
被删掉的是: green
['red', 'blue']

不带参数写 pop(),会删掉最后一个(栈的用法):

Python
nums = [1, 2, 3]
last = nums.pop()
print(last, nums)

输出:

输出
3 [1, 2]

clear:一键清空,但列表还在

Python
nums = [1, 2, 3]
nums.clear()
print(nums)

输出:

输出
[]

del:直接按位置删,或把整个列表删掉

Python
nums = [10, 20, 30]
del nums[1]
print(nums)

输出:

输出
[10, 30]

del nums 则会把 nums 这个变量整个删掉,之后再访问它会报错。一般不用,清空用 clear() 更稳妥。

写法按什么删还能拿回被删的元素吗
remove(内容)值(只删第一个)不能
pop(位置)索引能,返回值就是它
clear()全部不能,直接变空
del 列表[位置]索引不能
想「删掉某样东西,并且还要用它的内容」,用 pop,它一边删一边把值交还给你。只想清空,用 clear() 最直白。

七、找和数(index / count / in)

要在列表里「找东西」,有三个趁手的工具。

index:某个值在哪儿(第一次出现的位置)

Python
letters = ['a', 'b', 'c', 'b']
print(letters.index('b'))

输出:

输出
1

count:某个值出现了几次

Python
numbers = [1, 2, 2, 3, 2]
print(numbers.count(2))

输出:

输出
3

in:在不在里面(返回 True / False)

Python
list17 = [1, 2, 3]
print(2 in list17)
print(4 in list17)

输出:

输出
True
False

找不到会报错

index 和 remove 要找的值不存在时,会抛 ValueError:

Python
letters = ['a', 'b', 'c']
print(letters.index('z'))

运行后会报错(逐字照抄解释器):

报错
ValueError: 'z' is not in list
拿不准值在不在这个列表里,先用 in 判断一下再 index,能避免上面的 ValueError。
「在不在」用 in(安全、返回布尔值);「在的话第几个」用 index(不在会报错);「有几个」用 count。

AI 助手小贴士|append 和 extend 是列表的高频混淆点,一句话让 AI 讲透。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:append 和 extend 的区别是什么?[1,2].append([3,4]) 和 [1,2].extend([3,4]) 各得到什么?再出 2 道题考我

八、排序与反转(sort 与 sorted 的区别、sort 返回 None)

把列表排个序,是日常高频操作。这里有个大坑必须先说。

sort:原地排序,不返回新列表

Python
nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort()
print(nums)

输出:

输出
[1, 1, 2, 3, 4, 5, 6, 9]

坑:sort() 返回的是 None

很多人写 sorted_nums = nums.sort(),以为拿到了排好序的列表,其实拿到的是 None:

Python
nums = [3, 1, 2]
result = nums.sort()
print(result)

输出:

输出
None

sort() 是直接把原来的 nums 改掉了(原地排序),它自己不返回任何东西。想要「排好序的新列表又不动原列表」,用 sorted():

Python
nums = [3, 1, 4]
new_nums = sorted(nums)
print(new_nums)
print(nums)

输出:

输出
[1, 3, 4]
[3, 1, 4]

降序与反转

Python
nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort(reverse=True)
print(nums)

输出:

输出
[9, 6, 5, 4, 3, 2, 1, 1]

reverse() 是把顺序整个倒过来,跟大小无关:

Python
nums = [1, 2, 3, 4, 5]
nums.reverse()
print(nums)

输出:

输出
[5, 4, 3, 2, 1]
写法动不动原列表返回什么典型用途
nums.sort()动(原地改)None就想把原列表排好
sorted(nums)不动新列表要留着原列表,另存一份排好序的
nums.reverse()动None把顺序倒过来
一句话记住:sorted() 是内置函数,任何序列都能用,会把排好序的新列表还给你;sort() 是列表自己的方法,直接把原列表改掉,自己什么都不还(返回 None)。

课程思政|诚信与职业操守 · 改没改原表,要说清楚

nums.sort() 直接把原列表改了、只返回 None;sorted(nums) 则不动原表,给你一份新的。两种做法都没错,关键是心里清楚自己在动谁,并且让读代码的人一眼看明白。含糊其辞才是真的大坑。命名、注释、返回值,都在替你把话说清楚——这既是严谨,也是对同事的诚实。

九、改元素与列表相加相乘

列表里的元素可以单独改,也可以整体拼接、复制。

改某一个元素

Python
a = [1, 2, 3]
a[1] = 20
print(a)

输出:

输出
[1, 20, 3]

两个列表相加:拼成一个更长的

Python
list12 = [1, 2, 3]
list13 = [4, 5, 6]
list14 = list12 + list13
print(list14)

输出:

输出
[1, 2, 3, 4, 5, 6]

列表乘以数字:重复 N 遍

Python
list15 = [1]
list16 = list15 * 3
print(list16)

输出:

输出
[1, 1, 1]

注意:加和乘都不会改原来的列表,而是产生一个新列表。原列表想变,得自己重新赋值:

Python
a = [1, 2, 3]
a = a + [4, 5]
print(a)

输出:

输出
[1, 2, 3, 4, 5]
别把 + 和 append 搞混:a = a + [4] 得到新列表;a.append(4) 直接改原列表。也别写 [1,2,3] + 4 —— 列表只能和列表相加,加数字会报错(见报错手册)。
想快速复制一串相同内容,乘法很方便:zeros = [0] * 5 得到 [0,0,0,0,0]。但里面若是列表要小心(见常见坑第 6 条)。

十、常用内置函数与列表推导式

Python 自带几个函数,专门伺候列表这类「一串东西」。

Python
list18 = [1, 2, 3, 4, 5]
print("长度:", len(list18))
print("最大:", max(list18))
print("最小:", min(list18))
print("总和:", sum(list18))

输出:

输出
长度: 5
最大: 5
最小: 1
总和: 15

列表推导式:一行生成列表

这是 Python 很爽的写法:用一行,按规则「变」出一个列表。先看三个例子体会一下:

Python
squares = [i**2 for i in range(1, 11)]
print("1~10 平方:", squares)

输出:

输出
1~10 平方: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

意思是:让 i 从 1 走到 10,把每个 i**2 收进列表。

Python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even = [i for i in numbers if i % 2 == 0]
print("偶数:", even)

输出:

输出
偶数: [2, 4, 6, 8, 10]

这次多了 if i % 2 == 0:只收偶数。

Python
list22 = [1, 2, 3]
str_list = [str(i) for i in list22]
print("变成文字:", str_list)

输出:

输出
变成文字: ['1', '2', '3']

把每个数字用 str() 转成文字。

再来一个中国味的:从《春晓》里把「春」「晓」两个字挑出来——条件里的 in 也能判断「这个字在不在那串字里」:

Python
poem = '春眠不觉晓处处闻啼鸟'
chars = [c for c in poem if c in '春晓']
print(chars)

输出:

输出
['春', '晓']

推导式的基本长相:[表达式 for 变量 in 一串东西 if 条件]。

推导式一开始可能绕,先把它读成中文:「对这串东西里的每一个,算出表达式的值,满足条件就收进新列表」。不用强求一步到位,用 for 循环也能做,熟练了再换推导式。

十一、多维列表(列表里装列表)

列表的元素可以是任何东西——包括另一个列表。当每个元素本身也是列表时,就成了多维列表(也叫嵌套列表、二维列表)。它最适合表示一张「表格」:一行一个学生,一列一项数据。

Python
students = [
    ['小明', 92, 88],
    ['小红', 76, 95],
    ['小刚', 85, 79],
]

怎么读它?先把它看成「3 个元素」,每个元素本身又是一个列表。要取到具体的数,就从左到右一层层往里钻:

Python
students = [['小明', 92, 88], ['小红', 76, 95], ['小刚', 85, 79]]
print(students[0])        # 第 1 行(整行)
print(students[0][0])     # 第 1 行第 1 列
print(students[1][2])     # 第 2 行第 3 列

输出:

输出
['小明', 92, 88]
小明
95

students[0] 是整行(一个列表),students[0][0] 才是格子里那个值。两个中括号,前一个选行、后一个选列。

别把 students[0][0] 写成 students[0, 0]——普通列表不支持这种写法,会报 TypeError。

用双层 for 遍历

Python
students = [['小明', 92, 88], ['小红', 76, 95]]
for row in students:        # 外层:一行一行拿
    for value in row:       # 内层:把这行的每一格拿出来
        print(value, end=' ')
    print()

输出:

输出
小明 92 88 
小红 76 95 

常见用法:按行算总分

Python
students = [['小明', 92, 88], ['小红', 76, 95], ['小刚', 85, 79]]
for row in students:
    name = row[0]
    total = sum(row[1:])     # 从第 2 列开始求和
    print(name, '总分', total)

输出:

输出
小明 总分 180
小红 总分 171
小刚 总分 164

矩阵:一个 3×3 的数字方阵

Python
m = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]
print(m[1][2])       # 第 2 行第 3 列
print(m[2][0])       # 第 3 行第 1 列

输出:

输出
6
7

坑:[[0] * 3] * 3 造出来的三行其实是「同一行」

Python
bad = [[0] * 3] * 3
bad[0][0] = 9
print(bad)          # 三行一起变了!

输出:

输出
[[9, 0, 0], [9, 0, 0], [9, 0, 0]]

原因:[X] * 3 是把同一个 X(同一个列表对象)重复了三遍,三个位置指向的是同一行。正确写法是用推导式,让每行都新建一个:

Python
good = [[0] * 3 for _ in range(3)]
good[0][0] = 9
print(good)         # 只有第 1 行变

输出:

输出
[[9, 0, 0], [0, 0, 0], [0, 0, 0]]
查二维列表时,脑子里默念「先选行、再选列」:m[行][列]。看到 list[i][j] 就读成「第 i 行的第 j 个」。

十二、迭代器:for 背后到底发生了什么

你早就习惯了写 for x in 列表:。但 for 到底怎么把元素一个个拿出来的?答案是:列表先「生产」出一个迭代器,for 每次从迭代器里取一个,取完为止。

手动取:iter() 与 next()

Python
nums = [10, 20, 30]
it = iter(nums)        # 把列表变成迭代器
print(next(it))        # 取第 1 个
print(next(it))        # 取第 2 个
print(next(it))        # 取第 3 个

输出:

输出
10
20
30

取完了还取,会抛 StopIteration

Python
it = iter([1, 2])
print(next(it))
print(next(it))
print(next(it))       # 没有第 3 个了

运行后最后一行报错是:

输出
StopIteration

for 循环内部其实就在做这件事:不停地 next(),一旦收到 StopIteration 就安静地结束——所以平时你根本看不到这个异常。

迭代器是「一次性」的

Python
nums = [1, 2, 3]
it = iter(nums)
print(list(it))      # 第一次:全取出来了
print(list(it))      # 第二次:空了!

输出:

输出
[1, 2, 3]
[]

可迭代对象 vs 迭代器

可迭代对象(Iterable)迭代器(Iterator)
特征能被 for 遍历既能被 for 遍历,也能 next()
必备方法__iter____iter__ 和 __next__
能不能反复用能(每次都重新开一个迭代器)不能,取完就废
例子列表、字符串、字典、集合、rangeiter([1, 2, 3]) 的结果

一句话:列表是「可迭代对象」,但它本身不是「迭代器」。要被 iter() 包装一下,才得到真正的迭代器。

平时写代码根本不用手动 iter() / next(),直接 for 就行。这一节只是为了让你知道 for 的背后是什么——第 24 篇《生成器与迭代器》会顺着这套机制继续往下讲。

AI 助手小贴士|列表的基本操作齐了,来三道综合题验收。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:出 3 道列表综合题:去重但保持原来的顺序、把两个等长列表拼成字典、删除列表里所有的偶数。等我写完再对答案

课程思政|科技自立自强 · 循环背后到底怎么走

大家用了无数遍 for x in 列表,却很少想它背后先 iter() 取到迭代器、再不停 next(),取完抛出 StopIteration 才默默收场。数据库、编译器、AI 框架,底层都是这样一层层「取下一个」搭起来的。别只停在会用的层面,多问一句「它内部怎么走」,才可能从使用者变成创造者。

十三、十个基础案例

下面十个例子都很短,建议每个都亲手敲一遍、跑一遍。

1. 这顿外卖平均每样多少钱

Python
prices = [12, 18, 25, 9]
print('平均每样:', sum(prices) / len(prices))

输出:

输出
平均每样: 16.0

2. 最贵和最便宜的那件

Python
prices = [12, 18, 25, 9]
print('最贵', max(prices), '最便宜', min(prices))

输出:

输出
最贵 25 最便宜 9

3. 数一数有几件超过 20 元

Python
prices = [12, 18, 25, 30, 9]
over = 0
for p in prices:
    if p > 20:
        over += 1
print('超过 20 元的有:', over)

输出:

输出
超过 20 元的有: 2

4. 把价格从高到低排好

Python
prices = [12, 18, 25, 9]
prices.sort(reverse=True)
print(prices)

输出:

输出
[25, 18, 12, 9]

5. 购物车里再加一件

Python
cart = ['奶茶', '炸鸡']
cart.append('薯条')
print(cart)

输出:

输出
['奶茶', '炸鸡', '薯条']

6. 减掉不想要的那件

Python
cart = ['奶茶', '炸鸡', '薯条']
cart.remove('炸鸡')
print(cart)

输出:

输出
['奶茶', '薯条']

7. 从歌单里取出一段

Python
playlist = ['起风了', '晴天', '稻香', '七里香', '告白气球']
print(playlist[1:4])

输出:

输出
['晴天', '稻香', '七里香']

8. 看看好友在不在群里

Python
members = ['阿伟', '小美', '老王']
print('小美' in members)
print('大熊' in members)

输出:

输出
True
False

9. 电影票统统打八折

Python
prices = [50, 45, 60]
sale = [int(p * 0.8) for p in prices]
print(sale)

输出:

输出
[40, 36, 48]

10. 把两个购物车并起来

Python
cart1 = ['奶茶', '炸鸡']
cart2 = ['薯条', '可乐']
print(cart1 + cart2)

输出:

输出
['奶茶', '炸鸡', '薯条', '可乐']
这些案例覆盖了加、删、查、排序、求和、推导式。把它们敲熟,列表的日常用法就掌握了一大半。

十四、常见坑

坑 1:两个变量指向同一个列表(别名陷阱)

写 b = a 并不是复制,而是让 b 和 a 指向同一个列表。改了 b,a 也跟着变:

Python
a = [1, 2, 3]
b = a
b.append(4)
print('a 也变了:', a)

输出:

输出
a 也变了: [1, 2, 3, 4]

想要一份独立的副本,用 copy():

Python
a = [1, 2, 3]
b = a.copy()
b.append(4)
print('a 没变:', a)
print('b 是副本:', b)

输出:

输出
a 没变: [1, 2, 3]
b 是副本: [1, 2, 3, 4]

坑 2:sort() 返回 None,别赋值给新变量

Python
nums = [3, 1, 2]
new_nums = nums.sort()
print(new_nums)

输出:

输出
None

想要新列表又不动原列表,用 sorted(nums)(见第八节)。

坑 3:remove 只删第一个,而且值不在会报错

Python
nums = [1, 2, 2, 3]
nums.remove(2)
print(nums)

输出:

输出
[1, 2, 3]

列表里有两个 2,remove(2) 只删掉最前面的那个。要全删得用循环或推导式。

坑 4:pop() 不带参数删的是最后一个

Python
nums = [1, 2, 3]
nums.pop()
print(nums)

输出:

输出
[1, 2]

坑 5:索引从 0 开始,数错一位

Python
fruits = ['苹果', '香蕉', '橙子']
print('第 2 个其实是索引 1:', fruits[1])

输出:

输出
第 2 个其实是索引 1: 香蕉

坑 6:乘法复制里的列表是「共享」的

[[]] * 3 造出三个指向同一个空列表的格子,改其中一个,三个一起变:

Python
grid = [[]] * 3
grid[0].append(1)
print(grid)

输出:

输出
[[1], [1], [1]]
坑 1 和坑 6 本质一样:列表是「引用」。多个名字指向同一个列表时,改一处处处变。需要独立副本就用 copy();需要独立的小列表就用推导式 [[] for _ in range(3)]。
判断两个变量是不是同一个列表,用 is:a is b 为 True 就说明它们共享一个列表,要当心。

十五、报错手册

下面这些报错都是本机真实运行出来的,照抄解释器原文。看到眼熟的,直接对照处理。

索引越界 IndexError

Python
lst = [1, 2, 3]
print(lst[5])

运行后会报错(逐字照抄解释器):

报错
IndexError: list index out of range

原因:列表只有 3 个元素(索引 0~2),去拿第 5 个当然没有。先用 len() 看长度。

找不到值 ValueError

Python
lst = [1, 2, 3]
print(lst.index(99))

运行后会报错(逐字照抄解释器):

报错
ValueError: 99 is not in list

原因:index / remove 要找的值不存在。先用 in 判断在不在。

Python
lst = [1, 2, 3]
lst.remove(99)

运行后会报错(逐字照抄解释器):

报错
ValueError: list.remove(x): x not in list

方法名拼错 AttributeError

Python
lst = [1, 2, 3]
lst.appendd(4)

运行后会报错(逐字照抄解释器):

报错
AttributeError: 'list' object has no attribute 'appendd'. Did you mean: 'append'?

原因:append 多打了一个 d。较新的 Python 3 版本会贴心地提示你「你是不是想写 append」。

列表加数字 TypeError

Python
lst = [1, 2, 3]
print(lst + 4)

运行后会报错(逐字照抄解释器):

报错
TypeError: can only concatenate list (not "int") to list

原因:列表只能和列表相加。[1,2,3] + [4] 才行,或者改用 append(4)。

变量没定义 NameError

Python
print(lst[0])

运行后会报错(逐字照抄解释器):

报错
NameError: name 'lst' is not defined. Did you mean: 'list'?

原因:lst 还没创建就用了。创建列表后再访问。

括号没闭合 SyntaxError

Python
lst = [1, 2, 3

运行后会报错(逐字照抄解释器):

报错
SyntaxError: '[' was never closed

原因:少了一个右方括号。代码里的括号(圆、方、花)必须成对出现。

range 里写了字符串 TypeError

Python
print(list(range('5')))

运行后会报错(逐字照抄解释器):

报错
TypeError: 'str' object cannot be interpreted as an integer

原因:range() 只收整数。字符串 '5' 要先 int() 转换。

下标用了全角逗号也会出怪错

Python
lst = [1, 2, 3]
print(lst[1,2])

运行后会报错(逐字照抄解释器):

报错
SyntaxError: invalid character ',' (U+FF0C)

原因:不小心用了中文全角逗号 ,。Python 只认英文半角标点,写代码时切到英文输入法。

报错信息不要怕,它其实在告诉你「哪错了」。TypeError 通常是类型不对(列表加了数字、下标用了字符串);ValueError 是值不合适(找不存在的东西);IndexError 是位置超了。先看最后一行的类型,再往回查。

AI 助手小贴士|列表方法十来个,不用背。让 AI 出速查表,再让它出题考你——「被考」是检验学会的最快方式。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:列出 Python 列表最常用的 8 个方法(增删改查排序),每个配一行示例代码,然后出 3 道列表操作小题考我

十六、随堂自测(12 题)

点击选项即可判分,选错的题会立刻展开解析。做完可以看到正确率和错题清单,也可以重新答题。

已答 0 / 12 · 正确 0 —

1列表的索引是从几开始数的?

  • A. 从 0 开始
  • B. 从 1 开始
  • C. 从 -1 开始
  • D. 随机,每次都不一样
答案:A。Python 列表索引从 0 开始,第一个元素是 lst[0],第二个是 lst[1]。这是新手最容易数错的地方,记住「第几个减一」就是索引。

2执行 lst = [1, 2, 3, 4] 后,lst[2] 的值是?

  • A. 1
  • B. 2
  • C. 3
  • D. 4
答案:C。索引 2 是「第 3 个」元素,也就是 3。索引从 0 数:0→1,1→2,2→3。

3负索引 lst[-1] 表示列表里的哪个元素?

  • A. 第 1 个
  • B. 最后一个
  • C. 倒数第 2 个
  • D. 会报错
答案:B。负数从右边数,-1 是最后一个,-2 是倒数第二个。它和 lst[len(lst)-1] 是同一个位置。

4下面哪一行能正确创建一个空列表?

  • A. lst = ()
  • B. lst = {}
  • C. lst = ""
  • D. lst = []
答案:D。空列表用方括号 []。() 是空元组,{} 是空字典,"" 是空字符串,都不是列表。

5从 [1, 2, 3] 里 remove(99) 会发生什么?

  • A. 什么都不做
  • B. 删除最后一个元素
  • C. 报 ValueError
  • D. 报 IndexError
答案:C。remove 按值删,找不到 99 就抛 ValueError: 99 is not in list。删之前先用 in 判断在不在更安全。

6nums = [1, 2, 3],执行 nums.pop()(不带参数)会怎样?

  • A. 删除第 1 个元素
  • B. 删除最后一个元素并把它返回
  • C. 把整个列表清空
  • D. 报错
答案:B。pop() 不带参数时删掉最后一个元素,并且把删掉的值交还给你。想删指定位置就写 pop(位置)。

7nums = [3, 1, 2] 执行 nums.sort() 后,再 print(nums) 输出?

  • A. [3, 1, 2]
  • B. [1, 2, 3]
  • C. None
  • D. 报错
答案:B。sort() 是原地排序,直接把 nums 改成 [1, 2, 3],打印 nums 看到的就是排好序的结果。

8执行 print(nums.sort()) 会打印出什么?

  • A. [1, 2, 3]
  • B. nums
  • C. None
  • D. 报错
答案:C。sort() 只改原列表、自己不返回任何东西,所以它返回 None。想要排好序的新列表要用 sorted(nums)。

9下面哪一行代码会报 TypeError?

  • A. lst = [1, 2, 3]
  • B. lst.append(4)
  • C. lst[0] = 10
  • D. lst + 5
答案:D。列表只能和列表相加,lst + 5 会报 can only concatenate list (not "int") to list。正确是 lst + [5] 或 lst.append(5)。

10列表推导式 [i * 2 for i in range(3)] 的结果是?

  • A. [0, 2, 4]
  • B. [2, 4, 6]
  • C. [0, 1, 2]
  • D. [1, 2, 3]
答案:A。range(3) 给 0,1,2,每个乘 2 得到 0,2,4。推导式就是「对每个 i 算 i*2 收进新列表」。

11m = [[1, 2], [3, 4]],那么 m[1][0] 的值是?

  • A. 3
  • B. 1
  • C. 2
  • D. [3, 4]
答案:A。m[1] 先拿到第 2 行 [3, 4],再 [0] 取这行的第 1 个,也就是 3。两层中括号要从左往右一层层往里钻。

12关于迭代器,下面说法正确的是?

  • A. 迭代器可以反复使用,取完还能回头再取
  • B. next() 取不到元素时会返回 None
  • C. 列表本身就是迭代器
  • D. 迭代器取完后再取会抛 StopIteration
答案:D。迭代器是「一次性」的,元素取完后再 next() 会抛 StopIteration(for 会自动接住它并结束循环)。列表是可迭代对象,要用 iter() 包装一下才得到迭代器。