1. 可变类型与不可变类型
2. 浅拷贝与深拷贝
常见可变类型数据有:列表、字典、集合
修改数据时,变量指向的内存地址不会发生改变
常见的不可变类型数据有:数值、字符串、元祖
修改数据时,变量会重新指向一块存储了新值的内存新起始地址
#定义一个列表----可变类型
>>> a=[1,2,3]
#查看该列表的内存地址
>>> id(a)
2418459139528
>>> a
[1, 2, 3]
#对列表进行修改,添加一个元素
>>> a.append(6)
>>> a
[1, 2, 3, 6]
#再次查看该变量的内存地址
>>> id(a)
2418459139528 #没有发生改变,还是最初的内存地址#定义一个字符串----不可变类型
>>> b = 'zifuchuan'
#查看最初的内存地址
>>> id(b)
2418469351920
#将字符串进行拼接
>>> b += '拼接'
>>> b
'zifuchuan拼接'
#查看拼接后的内存地址
>>> id(b)
2418469900528 #内存地址发生改变了
import copy #导入拷贝模块 (python默认的赋值就是浅拷贝)
存储浅拷贝数据的变量 = copy.copy(被拷贝的数据变量)
浅拷贝只会拷贝对象的第一层地址引用,当对象存在多层时,对象的的深层数据发生更改,拷贝的数据也会发生更改,
因为他们都存储了一样的第一层地址,而第一层地址指向的数据发生了修改,拷贝的数据指向的也是相同的内存数据,自然也变了
import copy #导入拷贝模块
存储深拷贝数据的变量 = copy.deepcopy(被拷贝的数据变量)
深拷贝会将被拷贝的对象,逐层拷贝,所有的数据都会被重新创建一份,即拷贝后的所有数据与原先数据都不存在共享的内存空间
>>> a_list = ['a','b','c',1,2,3,[1,2,3]]
>>> import copy
>>> a = copy.copy(a_list)
>>> b = copy.deepcopy(a_list)
>>> id(a_list)
1994606042824
>>> id(a)
1994646072968
>>> id(b)
1994646073288>>> c = a_list
>>> id(c) 赋值使用的是引用
1994606042824
>>> a_list
['a', 'b', 'c', 1, 2, 3, [1, 2, 3]]
>>> a
['a', 'b', 'c', 1, 2, 3, [1, 2, 3]]
>>> b
['a', 'b', 'c', 1, 2, 3, [1, 2, 3]]
>>> c
['a', 'b', 'c', 1, 2, 3, [1, 2, 3]]修改原始数据的深层数据
>>> a_list[-1][0]="abcdef"
>>> a_list
['a', 'b', 'c', 1, 2, 3, ['abcdef', 2, 3]]
>>> a 浅拷贝的值也会发生改变
['a', 'b', 'c', 1, 2, 3, ['abcdef', 2, 3]]>>> b 深拷贝的值不会发生改变
['a', 'b', 'c', 1, 2, 3, [1, 2, 3]]
>>> c 系统默认的赋值,引用相当于是浅拷贝
['a', 'b', 'c', 1, 2, 3, ['abcdef', 2, 3]]
特点:深拷贝保证了数据的完全独立性,但需要占用更多的内存空间
浅拷贝只拷贝第一层数据,既节省了内存空间和拷贝时间,速度更快,但存在深层数据时可能会被修改
总结:Python的赋值,默认都是浅拷贝,完全不可变类型的数据拷贝都是浅拷贝
(完全不可变类型:如元祖不可变,可其中一个元素为可变列表,此时就可能会发生改变,
所以完全不可变类型就是不可变类型中也都是不可变类型的元素)
对象之间赋值本质上 是对象之间的引用传递而已。也就是多个对象指向同一个数据空间。