我们有时会需要一个空列表,用来在指定索引处赋值,比如我有一个空列表 L ,现在我需要直接在第7个位置赋值(L[7]=666),而不是常规的顺序赋值(用append追加元素),这时要怎么生成这个空列表呢?方法很简单,代码仅需一两行就够啦~
>>> dim_1 = [0 for index in range(8)] # 生成长度为8的零列表
>>> print(dim_1)
[0, 0, 0, 0, 0, 0, 0, 0]
>>> dim_1[7] = 666 # 将索引为7的元素赋值为666
>>> print(dim_1)
[0, 0, 0, 0, 0, 0, 0, 666]
如果我需要的是长度为8的二维列表呢?
>>> dim_1 = [0 for index in range(8)] # 生成长度为8的零列表
>>> dim_2 = [dim_1 for index in range(8)] # 生成行列均为8的零矩阵(二维列表)
>>> print(dim_2)
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]
>>> dim_2[7] = [666 for index in range(8)] # 将第7行列表中的8个值赋为666
>>> print(dim_2)
[[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [666, 666, 666, 666, 666, 666, 666, 666]]
貌似一切都很顺利,但是对单个元素进行赋值呢?
>>> dim_1 = [0 for index in range(8)]
... dim_2 = [dim_1 for index in range(8)]
>>> dim_2[0][0] = 1 # 对第0行第0列元素赋值
>>> print(dim_1)
[1, 0, 0, 0, 0, 0, 0, 0]
>>> print(dim_2)
[[1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0]]
结果却变成了上面酱紫,明显不是我们想要的结果。相信对指针比较熟悉的小伙伴已经看出端倪了。
dim_2 = [dim_1 for index in range(8)]
其实上面这种初始化一个二维列表的写法是非常危险的!!!这种做法只是将列表 dim_1 的首地址赋给了 dim_2 的8个指针,可以理解为 dim_2 是C语言中的长度为8的指针数组,数组中的每个指针变量中存储的都是 dim_1 的首地址,所以直接对 dim_2 的单个元素进行操作就是在 dim_1 所在内存空间中直接对其元素进行修改,才会导致“一呼百应”的现象。换句话来说,这是一种“浅复制”,要实现“深复制”,只要把上面这条语句改为
dim_2 = [list(dim_1) for index in range(8)]
list(dim_1)就相当于重新申请了一块新的内存空间,然后把 dim_1 的内容“深复制”到新的内存空间当中,这样就不会出现上述的奇怪现象了。
然后我们再来测试看下“深复制”的效果:
>>> dim_1 = [0 for index in range(8)]
... dim_2 = [list(dim_1) for index in range(8)]
... dim_2[0][0] = 1
>>> print(dim_1)
[0, 0, 0, 0, 0, 0, 0, 0]
>>> print(dim_2)
[[1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]
Pretty niiice!
本文表述可能不是很规范,只希望能给有需要的小伙伴提供一些简单的参考,如对指针或者其他部分有疑问的小伙伴欢迎在下面评论提问哦~