我们一起走过的坑:Python 生成包含空列表或全0列表的特定长度的列表list

我们有时会需要一个空列表,用来在指定索引处赋值,比如我有一个空列表 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!

 

本文表述可能不是很规范,只希望能给有需要的小伙伴提供一些简单的参考,如对指针或者其他部分有疑问的小伙伴欢迎在下面评论提问哦~

  • 20
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值