当前位置:网络安全 > Python---引用、可变类型与不可变类型,浅拷贝与深拷贝

Python---引用、可变类型与不可变类型,浅拷贝与深拷贝

  • 发布:2023-09-09 17:38

目录:

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的赋值,默认都是浅拷贝,完全不可变类型的数据拷贝都是浅拷贝

(完全不可变类型:如元祖不可变,可其中一个元素为可变列表,此时就可能会发生改变,

   所以完全不可变类型就是不可变类型中也都是不可变类型的元素)

对象之间赋值本质上 是对象之间的引用传递而已。也就是多个对象指向同一个数据空间。

 

相关文章