python中的浅拷贝、深拷贝和赋值的区别

在python中有深拷贝、浅拷贝和赋值。那么怎么去理解呢?

  • 浅拷贝:指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。只拷贝第一层级的所有元素,单独开辟空间成型独立的一份副本。(类似[1,2,3]第一层级)
  • 深拷贝:是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。所有层级的元素都单独拷贝一份,开辟新的空间。(类似[1,2,3,[1,2,3]])
  • 赋值:将变量和值在内存中形成映射指向关系。

一、浅拷贝

  • 通过自己的数据类型构建
  • 可变类型的数据,可以通过切片
  • Python中的copy模块导入

1.1通过自己的数据类型构建:

list1 = [1,2,3]
list2 = list(list1)
print(list1 is list2) # False
print(list1 == list2) # True

set1 = {1,2,3}
set2 = set(set1)
print(set1 is set2)# False
print(set1 == set2)# True

str1 ='123'
str2 = str(str1)
print(str1 is str2) # True
print(str1 == str2)# True
dict1 = {"a":1,"b":2}
dict2 = dict(dict1)
print(dict1 is dict2) # False
print(dict1 == dict2) # True

 因此,在浅拷贝中,为新变量重新分配一块内存,和原来变量的内存不一样只针对可变数据类型而已),但是针对不可变数据类型,发现这个内存地址是一样的。而不管可变数据还是不可变数据类型,两个变量中的元素的值是一样的

1.2可变数据类型通过切片:(内存地址不一样)

list1 = [1,2,3]
list2 = list1[:]
print(list1 is list2)# False
print(list1 == list2)# True

1.3不可变数据类型通过切片:(内存地址一样)

a = (1,2,3)
b = a[:]
print(a is b) # True
print(a == b) # True

1.4使用 copy.copy() 函数:

import copy
list1 = [1,2,3]
list2 = copy.copy(list1)
print(list1 is list2) # False
print(list1 == list2) # True

str1 = '123'
str2 = copy.copy(str1)
print(str1 is str2) # True
print(str1 == str2) # True

tup1 = (1,2,3)
tup2 = copy.copy(tup1)
print(tup1 is tup2) # True
print(tup1 == tup2) # True

set1 = {1,2,3}
set2 = copy.copy(set1)
print(set1 is set2) # False
print(set1 == set2) # True

dict1 = {"a":1,"b":2}
dic2 = copy.copy(dict1)
print(dict1 is dic2) # False
print(dict1 == dic2) # True

1.5不能使用切片来操作字典和集合:

dict1 = {"a":1,"b":2}
dict2 = dict1[:]
print(dict2) # 报错

set1 = {1,2,3}
set2 = set1[:]
print(set2) # 报错

二、赋值

  • 赋值,只是把原对象的引用给到新对象。其实指向的内存地址是同一个。
  • list1 = [1,2,3] list2 =list1 print(list1 is list2) #True print(list1 == list2) #True list1.append(4) #list1 [1, 2, 3, 4] print("list1",list1) #list2 [1, 2, 3, 4] print("list2",list2) print(list1 is list2)#True print(list1 == list2) #True str1 = '123' str2 = str1 print(str1 is str2) # True print(str1 == str2) # True str3 = str1 + '456' print(str3) # 123456 print(str1) # 123
set1 = {1,2,3}
set2 = set1
set1.add(4)
print(set1) # {1,2,3,4}
print(set2) # {1,2,3,4}
print(set1 is set2) # True
# 如其他数据类型也是一样

  因此,赋值中,可变类型,如果一个变量变化,那么另外一个变量也会发生变化。不可变类型,如果一个变量变化,另外一个变量不会发生变化。内存地址发生了变化。

三、深拷贝

  • Python 中以 copy.deepcopy() 来实现对象的深度拷贝

 

import copy

list1 = [1,2,3]
list2=copy.deepcopy(list1)
print(list1 is list2)  # False
print(list1 == list2)  # True
list1.append(4)
print(list1,id(list1)) # [1, 2, 3, 4] 2707129915008
print(list2,id(list2)) # [1, 2, 3] 2707129914752
tup1 = (1,2,3)
tup2 = copy.deepcopy(tup1)
print("tup1",id(tup1))
print("tup2",id(tup2))
print(tup1 is tup2) # True
print(tup1 == tup2) # True

 

  在深拷贝中,可变数据类型,拷贝后内存地址不一样,而对于不可变数据类型而言,深拷贝后内存地址还是同一块。但两者都是如果变量发生变化,另外一个变量就不会跟着发生变化。

 

参考:https://blog.csdn.net/qq_40630902/article/details/119278072

 

posted on 2022-09-21 15:30  一先生94  阅读(258)  评论(0编辑  收藏  举报

导航