python生成矩阵为何[[0 for i in range(n)] for j in range(m)]而不能[[0]*n]*m

python生成矩阵,使用[[0]*n]*m,我们会发现,当改变其中某一个元素时,整列数据都会发生改变,而使用[[0 for i in range(n)] for j in range(m)]才可以生成正常的矩阵。

这是因为,list是可变元素,而int是不可变元素,对于list存储采用指针,引用型变量,改变矩阵其中某一个元素值,导致所有行的这个位置的元素都会改变。下面具体分析:

1、python列表的存储形式

在这里插入图片描述

Python列表和C语言数组不同,并不是存的实在的值,而是存放的只想其他实例的指针。所以也就能够理解 为什么python列表里里面什么东西都可以放进去而不需要考虑类型了~

2、 [0] * 2的存储形式

在这里插入图片描述

这里的 0 是同一个实例,可以通过以下代码发现这点~
(id表示查看实例的唯一标识符~)
在这里插入图片描述

3、 [[0]*2]*2的存储形式

在这里插入图片描述

下面两个箭头代表着下面的两行其实就是指向第一行两个指针,所以这里更改任意一行,都会对其他行产生影响,如图:

在这里插入图片描述
这里明明只更改了第三行的第三个元素,但是所有行的第三个元素都发生了变化,所以这也说明了指针这一特性,[[0]2]2所产生的其他行都 只是简单的指向第一行,不是进行复制 **,所以更改任意一行,其他行都会产生变化!

4、 [[0 for i in range(3)] for j in range(3)]

虽然里面所有的0 都是一个实例,但是进行修改时,修改的是不同的列表,如图:
在这里插入图片描述
(这里的lst就是用上面的 [[0]*3]*3来产生的,而another是由列表解析式产生的),可以看出,lst每一行的id都是一样的,而another是不一样的,即代表着不同的行,修改其中一行并不会对另外的行产生影响。

也有小伙伴会问了,那列表解析式里面每个元素都是同一个,修改其中一个难道不会对其他有影响吗,这里我贴出一下代码,朋友们可以自行测试一下。

aa = [0 for i in range(3)]          # 不可变类型
for i in aa: print(id(i))

aa = [[0] for i in range(3)]        # 可变类型
for i in aa: print(id(i))

aa = ['1' for i in range(3)]        # 不可变类型
for i in aa: print(id(i))

aa = [(1,2) for i in range(3)]      # 不可变类型
for i in aa: print(id(i))

不可变类型修改的时候是创建一个全新的实例,如果每个id都不一样的话,会非常耗费内存,而且一般不会对其他东西有影响,所以就创建相同的实例,但是可变类型不能这样,可变类型如果id相同,那么修改他们的元素会对其他实例产生影响,所以每个实例都应该是一个全新的实例

归根结底,还是我这里第一条所概述的,Python的列表存储方式是用的指针指向实例地址来存储的,列表里面放的就是指针的地址。

所以,君不见python里面没有指针,但是指针始终如影随形。😁

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Weiyaner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值