Python嵌套列表
困难0把列表装进列表——Python嵌套列表入门
上次我们学会了用列表来管理数据,比如一张购物清单。但数据有时候会有“层级结构”——比如一个班级有好几个小组,每个小组里有几个同学;或者一个书包里有几个文具盒,每个文具盒里装着不同的笔。这时候,普通的列表就不够用了,我们需要嵌套列表,也就是“列表里面再套一个列表”,就像大盒子里装小盒子,小盒子里再装东西。
什么是嵌套列表?
嵌套列表,就是列表中的元素本身也是列表。创建它就像平常写列表一样,只不过元素变成了列表。
生活中的例子:
- 班级分组:班级 → 小组 → 同学
- 超市货架:货架 → 类别(零食、饮料)→ 商品
- 游戏地图:整个地图 → 每一行 → 每个格子
看看下面这个代码,它表示一个班级的分组情况:
class_room = [ # 大列表:整个班级
["小明", "小红", "小刚"], # 子列表1:第一组
["小华", "小丽"], # 子列表2:第二组(只有2人)
["小强", "小美", "小杰"] # 子列表3:第三组
]
# 注意:每个子列表长度可以不一样,第二组只有2个人,其他都是3人
除了直接写,还能用两种常见方式创建空嵌套列表:
# 方式1:先建一个空列表,再添加子列表
team_list = [] # 空的大列表
team_list.append(["Alice", "Bob"]) # 添加第一个小组
team_list.append(["Cathy"]) # 添加第二个小组(只有一个人)
# 方式2:用列表推导式生成(稍复杂,先了解)
matrix = [[i * j for j in range(3)] for i in range(3)] # 生成3x3矩阵
print(matrix) # 输出:[[0, 0, 0], [0, 1, 2], [0, 2, 4]]
如何访问嵌套列表中的元素?
要找到嵌套列表里的某个具体数据,需要两个索引(下标):
- 第一个索引:选择哪个子列表(第几组)
- 第二个索引:选择那个子列表里的第几个元素(组里第几个人)
索引从 0 开始,就像排队时第1个人对应编号0。
print(class_room[0]) # 输出第一组所有同学:['小明', '小红', '小刚']
print(class_room[0][1]) # 输出第一组第2个人:小红
print(class_room[2][0]) # 输出第三组第1个人:小强
你可以想象成“第几排第几个座位”:
class_room[2][0]→ 第3排(索引2)第1个座位(索引0)
如果只给一个索引,得到的是整个子列表:
group2 = class_room[1] # 得到第二组列表:['小华', '小丽']
print(group2[0]) # 小华
如何修改嵌套列表中的元素?
修改方法和普通列表一样,用=赋值,但要指定两个索引:
class_room[1][1] = "小花" # 把第2组的第2个人(原小丽)改成小花
print(class_room[1]) # 输出:['小华', '小花']
也可以修改整个子列表:
class_room[0] = ["新同学1", "新同学2"] # 第一组全部替换
如何遍历嵌套列表?
遍历嵌套列表通常需要双重循环:
- 外层循环:遍历每个子列表(每个小组)
- 内层循环:遍历当前子列表中的每个元素(每个同学)
方法1:直接用for变量
for group in class_room: # group是每个子列表
for student in group: # student是每个同学名字
print(student, end=" ") # 不换行,用空格隔开
print() # 每小组结束后换一行
输出:
小明 小红 小刚
小华 小花
小强 小美 小杰
方法2:用range和len(同时可以获取索引)
for i in range(len(class_room)): # i是小组索引
print(f"第{i+1}组共有{len(class_room[i])}人:", end="")
for j in range(len(class_room[i])): # j是组内索引
print(class_room[i][j], end=" ")
print()
输出:
第1组共有3人:小明 小红 小刚
第2组共有2人:小华 小花
第3组共有3人:小强 小美 小杰
新手最容易犯的错误
-
忘记两层索引,只写一个
print(class_room[0]) # 正确:得到子列表 print(class_room[0][1]) # 正确:得到具体元素 print(class_room[0, 1]) # 错误!Python不支持这样写,必须分开用方括号 -
索引超出范围
print(class_room[3][0]) # 错误:只有索引0、1、2(共3组),索引3不存在 print(class_room[0][5]) # 错误:第一组只有3个人,索引最大2注意:子列表长度可以不同,遍历前最好先确认长度。
-
误以为嵌套列表必须是矩形(行列相等) 实际上每个子列表长度可以不同,就像不同小组人数可以不同。在处理时要注意。
-
修改变量时误改了不该改的地方
a = [1, [2, 3]] b = a[1] # b是[2,3]的引用 b[0] = 99 # 这样会同时修改a中的子列表! print(a) # 输出:[1, [99, 3]]如果不希望这样,可以复制:
b = a[1].copy()或b = a[1][:]。
完整可运行的例子:学生成绩管理
假设一个班有3个学生,每个学生有语文、数学、英语三科成绩。用嵌套列表保存,然后计算每个人的总分和平均分。
# 学生成绩:每个子列表代表一个学生,里面是[语文, 数学, 英语]
scores = [
[88, 92, 76], # 学生1
[95, 87, 91], # 学生2
[78, 85, 90] # 学生3
]
# 遍历每个学生,计算总分和平均分
for i in range(len(scores)): # i从0到2
total = 0 # 当前学生总分初始为0
for score in scores[i]: # 遍历当前学生的各科成绩
total = total + score
average = total / len(scores[i]) # 平均分
print(f"学生{i+1}:总分{total},平均分{average:.1f}")
输出:
学生1:总分256,平均分85.3
学生2:总分273,平均分91.0
学生3:总分253,平均分84.3
如果要查找某个分数,比如第2个学生的数学成绩:
print(scores[1][1]) # 输出:87(第2个学生,第2科即数学)
相关知识点指引
- 三维列表(列表的列表的列表):比如保存多张游戏地图,每张地图又是二维的。访问需要三个索引。
- 列表推导式生成嵌套列表:
[[0]*5 for _ in range(3)]可以快速生成3行5列的零矩阵。 - 浅拷贝和深拷贝:当你复制嵌套列表时,
copy模块的deepcopy能避免修改副本影响原列表。 - 与NumPy数组的区别:如果处理大量数值计算(比如科学计算),更推荐NumPy的
ndarray,但理解嵌套列表是基础。
嵌套列表让Python能处理更复杂的数据结构,比如棋盘游戏、表格数据、分组统计等。试着用它来管理你的零花钱账本(按月份、按类别)或者做一个班级座位表吧!
例题精讲
已知列表 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],要访问数字 5,下列哪个表达式是正确的?
给定嵌套列表 nested = [[1, 2], [3, 4, 5], [6]],以下哪个代码能正确遍历并打印每个元素?
执行以下代码后,list1 和 list2 会同时受影响。list1 = [[1, 2], [3, 4]]; list2 = list1; list2[0][0] = 0
请补全代码,创建一个 3 行 4 列(每行初始为0)的嵌套列表,并赋值给变量 grid。\ngrid = ___ for _ in range(3)]以下代码计算嵌套列表 matrix 中所有元素的和,请补全空缺部分。\ndef sum_matrix(matrix):\n total = 0\n for row in matrix:\n for elem in ___ :\n total += elem\n return total