python嵌套列表知多少

    科技2025-09-24  77

    今天在创建嵌套列表时遇到一个问题,决定看看到底是谁在背后捣鬼

    >>> board1 = [[0]*3 for _ in range(3)] [[0, 0, 0], [0, 0, 0], [0, 0, 0]] >>> board2 = [[0]*3]*3 [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

    没错,看起来两种方法都可以创建嵌套列表,但是赋值的时候却出现了问题

    >>> board1[1][1] = 1 [[0, 0, 0], [0, 1, 0], [0, 0, 0]] >>> board2[1][1] = 1 [[0, 1, 0], [0, 1, 0], [0, 1, 0]]

    查阅资料,发现这是 board2 列表内的 3 个引用指向同一个对象的原因。作为一只菜鸟,仍然不解其意,又看到了下面的例子

    ''' 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书! ''' >>> board3 = [] >>> for i in range(3): ... row=[0] * 3 ... board3.append(row) ... >>> board3 [[0, 0, 0], [0, 0, 0], [0, 0, 0]] >>> board3[1][1] = 1 >>> board3 [[0, 0, 0], [0, 1, 0], [0, 0, 0]]

    board3 和 board1 是一样的,每次迭代新建了一个列表,意味着列表的每行指向不同的地址。

    再看下面的例子

    ''' 遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书! ''' >>> board4 = [] >>> row=[0] * 3 >>> for i in range(3): ... board4.append(row) >>> board4 [[0, 0, 0], [0, 0, 0], [0, 0, 0]] >>> board4[1][1] = 1 >>> board4 [[0, 1, 0], [0, 1, 0], [0, 1, 0]]

    board4 和 board2 是一样的,每次迭代都添加同一个对象到列表,意味着列表的每行指向了同一块地址。 为什么会这样?

    这是引用和可变对象背后的原理和陷阱。

    python 中默认是做浅复制,假如list1 是一个列表,list(list1) 或 list1[:] 都会创建 list1 的副本,它们做的是浅复制(只复制了最外层容器,副本中元素依然是源容器中元素的引用)。浅复制共享同一个列表对象

    为了清楚的理解它们到底是如何运行的,我们将下面创建嵌套列表的过程进行可视化

    board1 = [[0]*3 for _ in range(3)] board1[1][1] = 1 board2 = [[0]*3]*3 board2[1][1] = 1

    第一行:

    首先创建一个可迭代对象,在循环体中创建[0]*3 赋值到新列表对应位置 可以看到,嵌套列表内每个子列表占用单独的空间,所以赋值操作 board1[1][1] = 1只会改变其中一个 第三行:

    嵌套列表内的三个子列表指向同一个对象,所以赋值操作会造成我们最初看到的情形。

    Processed: 0.014, SQL: 9