zoukankan      html  css  js  c++  java
  • python嵌套列表知多少

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

    >>> 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 个引用指向同一个对象的原因。作为一只菜鸟,仍然不解其意,又看到了下面的例子

    >>> 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 是一样的,每次迭代新建了一个列表,意味着列表的每行指向不同的地址。

    再看下面的例子

    >>> 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 只会改变其中一个

    第三行:

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

    大家可以在这里试着输入自己的代码,看看可视化执行过程。欢迎留言

  • 相关阅读:
    PYTHON核心编程第7章 7.5题
    openssl大漏洞
    运维之路
    组件嵌套+Mixin函数demo
    React初识(按钮点击+输入绑定)
    vue切换按钮(关闭消失型)
    动态发表之后的显示时间
    展开全部的实现
    前端进行后台数据的处理
    将项目上传到git上,并在测试服务器上运行
  • 原文地址:https://www.cnblogs.com/gongyanzh/p/12743501.html
Copyright © 2011-2022 走看看