CC++ & Algorithm

Python嵌套列表

困难0
语言版本:C++
概述:理解列表里还能装列表,就像书架上摆着不同的笔筒,每个笔筒里又装着笔。

把列表装进列表——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:用rangelen(同时可以获取索引)

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人:小强 小美 小杰 

新手最容易犯的错误

  1. 忘记两层索引,只写一个

    print(class_room[0])     # 正确:得到子列表
    print(class_room[0][1])  # 正确:得到具体元素
    print(class_room[0, 1])  # 错误!Python不支持这样写,必须分开用方括号
    
  2. 索引超出范围

    print(class_room[3][0])  # 错误:只有索引0、1、2(共3组),索引3不存在
    print(class_room[0][5])  # 错误:第一组只有3个人,索引最大2
    

    注意:子列表长度可以不同,遍历前最好先确认长度。

  3. 误以为嵌套列表必须是矩形(行列相等) 实际上每个子列表长度可以不同,就像不同小组人数可以不同。在处理时要注意。

  4. 修改变量时误改了不该改的地方

    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能处理更复杂的数据结构,比如棋盘游戏、表格数据、分组统计等。试着用它来管理你的零花钱账本(按月份、按类别)或者做一个班级座位表吧!

例题精讲

1单选题

已知列表 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],要访问数字 5,下列哪个表达式是正确的?

Amatrix[1][1]
Bmatrix[1][2]
Cmatrix[2][1]
Dmatrix[2][2]
2单选题

给定嵌套列表 nested = [[1, 2], [3, 4, 5], [6]],以下哪个代码能正确遍历并打印每个元素?

Afor i in range(len(nested)): print(nested[i])
Bfor sub in nested: for num in sub: print(num)
Cfor i in range(3): for j in range(2): print(nested[i][j])
Dfor sub in nested: print(sub)
3判断题

执行以下代码后,list1 和 list2 会同时受影响。list1 = [[1, 2], [3, 4]]; list2 = list1; list2[0][0] = 0

4填空题
请补全代码,创建一个 3 行 4 列(每行初始为0)的嵌套列表,并赋值给变量 grid。\ngrid = ___ for _ in range(3)]
5填空题
以下代码计算嵌套列表 matrix 中所有元素的和,请补全空缺部分。\ndef sum_matrix(matrix):\n    total = 0\n    for row in matrix:\n        for elem in ___ :\n            total += elem\n    return total