linux元组和列表的区别,Python中mutable与immutable和二维列表的初始化问题

初始化一个shape为(3,3)的二维列表,正确的写法是这样的:

a = [[None] * 3 for i in range(3)]

print(a)

a[0][0] = 1

print(a)

#经过测试没有问题

# 输出:

#[[None, None, None], [None, None, None], [None, None, None]]

#[[1, None, None], [None, None, None], [None, None, None]]

9110c87cde2533d7d2741b5fc03cf2b2.png

但是,如果写成这样:

a = [[None] * 3] * 3

print(a)

# 输出 : [[None, None, None], [None, None, None], [None, None, None]]

e089921a1c0297dd0fd2d11fc90a6d33.png

看起来像是没有问题,实际上,如果进行赋值操作,就会发现问题:

a[0][0] = 1

print(a)

# 输出:[[1, None, None], [1, None, None], [1, None, None]]

c77f4c8e2f9ad1ded9e22fa240614174.png

结果三行的对应位置的元素全都改变了!(就因为这个问题找了好长时间的bug… =_=|||)

后来知道,这个问题与Python中数据类型的分类有关,所以在这里记录一下,存个档。

步入正题,在Python中有一句话:万物皆对象(好像OOP都是这么说。。),在Python中所写的一切都可以看作是一个对象,比如定义的整数、浮点数以及列表,元组等,但是这些对象也有区别,这些对象,有些属于mutable(可变),有些则是属于immutable(不可变),这是什么意思呢?先看一个例子:

# 这里定义一个整数  id()函数可以查看对象的内存位置

a = 3

print(id(a))

a += 1

print(id(a))

#输出:

#  94034634295264

#  94034634295296

81f4aab37c46b9b531bc01ec7d444005.png

# 接下来定义一个列表:

a = [1,2,3]

print(id(a))

a[0] = 100

print(id(a))

# 输出:

#  139637076845448

#  139637076845448

b805676e39bc2b2fe8cfa8f2edc26fa2.png

通过对比,不难发现,对数值,比如整数、浮点数进行改变,内存的位置会发生改变,但是对列表,字典之类的进行改变,则不会改变内存位置。

实际上,对于整数、浮点数,改变值的时候,实际上是新开辟了一块内存,然后把加法的结果填充到这快内存中,然后再把a指向这块新的内存。

这里提到了“指向”,如果学过C或者C++,可能会想到指针或者引用,再Python中也有说引用的,那么这里就可以看出两种语言的“引用”是不同的了,C++中,对引用的数据进行改变,这个位置应该是不变的,而再Python中,显然,就像上面,相当于改变了“引用”,而不是内存的数据。

这里可能有点绕,不过这里也就是所说的mutable和immutable的问题了,在Python中,immutable的类型有整数、浮点数、字符串以及元组等等,而mutable的类型有list,dict以及自定义的类型。

那么回到上面一开始的问题中,知道了list是mutable的,所以在创建的时候,并不是赋值到了新的位置,只是创建了三个指针(a[0], a[1], a[2])指向了同一块内存而已,所以,改变其中一个的某个元素,会对所有的元素产生影响。

0b1331709591d260c1c78e86d0c51c18.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值