Python可变序列有那些坑?

249 阅读3分钟

先说点概念
在解释可变/不可变序列之前,先要知道什么是序列?序列就一个个元素有序地排列在一起,像小朋友”排排坐,吃果果“一样。

可变序列就是创建一个序列后,可以改变元素,可以比如成排好队小朋友之间位置可以换,可以插队等。可变序列包括列表和字典,集合。

不可变序列就是序列一旦创建后,就不可以修改了,可以比如成排好队地小朋友都十分地”拽“,不让人插队,不给换位置等操作。不可变序列包括元组,数值,字符串。

然后举个例子

例1

a=[1,2,3,4]
a[0] = 0 #对第一个元素进行赋值
a.append(5) #添加一个元素

因为list是可序列,所以对list进行修改是可以的。

但是对于不可变序列的元组是像列表那样操作,门都没有~ 例2

a=(1,2,3)
a[0]=1  #TypeError: 'tuple' object does not support item assignment

再看这个赋值代码 例3

a=1
a=2

你会不会觉得 a本来是1,是个数值,现在改成2了,这个序列不是改了吗?!!

非也非也~~,要知道变量不是盒子,更像一个”便签“,参考下图

在这里插入图片描述
便签的特点是什么?能贴能撕啊!!!撕了还能贴啊!!!

所以其实刚才例3的代码并没有把序列改了!,而是把便签从一个装有数值”1“的盒子撕下来,然后往装有数值“2”的盒子贴上!参考下图,从一个盒子贴上另外一个盒子。当然,这里的盒子其实是内存的比如,两个不同的盒子,两个不同的地址的内存。改的不是序列,而是换了一个地址!

在这里插入图片描述

来看多一个例子 例4,有一个列表,然后查看它的id和第一个元素id

a=['a','b','c']
print(id(a),id(a[0])#2024036167560 2024033353096

这说明,计算机给列表a分配了一个连续区域的地址,地址的为2024036167560,然后这片区域地址存放着一些字符串(实际上存放了对象的地址),然后每个对象都有自己的存放地址。参考下图

在这里插入图片描述
再看下面的例子5,因为是列表是可变序列,所以可以对元素进行修改

a=[['a'],'b','c']
print(id(a),id(a[0],id(a[0][0]]))#2910621259144 2910621265864 2910618451336
a[0]=['aaaa']
print(id(a),id(a[0]),id(a[0][0]))) #2910621259144 2910621241864 2910621246776

但是你会发现列表a,和a[0]的地址是没有改变的,因为它是可变序列,但是a[0][0]的地址却发生了改变,因为它是不可变序列,要改,只能创建新的对象,换地址。

可见操作可变序列不意味着总不会创建新的对象,这要具体看是什么操作!

公众号:CVpython,专注于分享Python和计算机视觉,我们坚持原创,不定期更新,希望文章对你有所启发,一起进步。