Python可变序列有那些坑?
先说点概念
在解释可变/不可变序列之前,先要知道什么是序列?序列就一个个元素有序地排列在一起,像小朋友”排排坐,吃果果“一样。
可变序列就是创建一个序列后,可以改变元素,可以比如成排好队小朋友之间位置可以换,可以插队等。可变序列包括列表和字典,集合。
不可变序列就是序列一旦创建后,就不可以修改了,可以比如成排好队地小朋友都十分地”拽“,不让人插队,不给换位置等操作。不可变序列包括元组,数值,字符串。
然后举个例子
例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和计算机视觉,我们坚持原创,不定期更新,希望文章对你有所启发,一起进步。