python中,可变数据类型,有:列表、集合、字典以及自定义类(未实现__hash__方法)
一、对可变数据类型赋值的2种情况
1、对“对象中的元素”进行赋值
不会创建新对象,内存地址保持不变。
ls1 = [1,2,3]
ls1[2] = 5
这里ls1的内存地址是不变的【也就是id(ls1)的值不会改变】
2、对象整体赋值
实质是创建了一个新对象,内存地址改变。
ls1 = [1,2,3]
ls1 = [9,3,2]
赋值时,没有针对单一元素或切片,那么实质是创建了一个新的对象(也就是前后2个ls1的内存地址不同)。
需要注意:
使用“=,等号”,将一个可变数据类型整体赋值给另一可变对象时,实质是将两个变量指向了同一对象(或者说创建了“指向同一对象的引用”)。
因此,改变其中一个变量的元素值,会引起另外一个变量的同时变化。
ls1 = [1,2,3]
ls2 = ls1
# 这时ls1,ls2的内存地址一致,
# 修改2个列表中,任意一个的元素值
# 会导致另一个的变化
#例如:
ls1[1] = 5
#会导致,2个列表都变成:[1,5,3]
二、赋值后,单独使用新对象的方法
对可变对象赋值时,摆脱对原对象的引用,使新的对象可以单独使用,有2种方法:
一方面,可以使用deepcopy(),另一方面,可以直接将其中一个对象的元素值赋给另一对象,例如:
ls1 = [1,3,5]
ls2 = ls1[:] #将ls1的元素赋值给ls2
这样ls2就是一个独立的可变对象。
三、使用fromkeys()方法,对字典对象初始化容易范的错误
这里很可能出现错误的是:使用{}.fromkeys()方法,对字典初始化:
d1 = {}.fromkeys(['sno','name','age'],['18321','小红',22])
这里创建的字典,3个键的值都是['18321','小红',22],修改其中任意一个键,都会影响到其它2个,比如:
d1['sno']=['18321','马丽',22]
那么,name和age的键值也会变得一模一样。
细节可以再看看: