浅复制 深复制 copy模块,copy.copy copy.deepcopy 前后是同一个对象吗

网友分享:

开辟一片新的内容,让这片内存的值完全等于a所指的内存值,然后让b指向这片新的内存;

C++ 浅拷贝相当于指针指向同一个地址,深拷贝是赋值一个数组,开辟新地址;

拷贝的数组里面的元素地址相同那是因为数字类型不可变,是Python的驻留机制问题,变了就是内存地址变化了,就是新的对象;

深拷贝做了3件事:开辟新地址,复制值,指针指向新地址。

********************************************************************************************************************************************************************************************************

复制列表(或多数内置的可变集合)最简单的方式是使用内置的类型构造方法。如l2 = list( l1 )

对列表和其他可变序列来说,还能使用简洁的l2 = l1[ : ]语句创建副本。

然而,构造方法或[:]做的是浅复制(即复制了最外层容器,副本中的元素是源容器中元素的引用)。如果所有元素都是不可变的,那么这样没有问题,还能节省内存。但是,如果有可变的元素,可能就会导致意想不到的问题。

 深复制(即副本不共享内部对象的引用)。copy模块提供的deepcopy和copy函数能为任意对象做深复制和浅复制。

 

import copy

copy.copy()
copy.deepcopy()

 

team = ['sue', 'Tina', 'Maya', 'Diana', 'Pat']

bus = list(team)

print(f'团队内存地址:{id(team)}, 公交车乘客内存地址:{id(bus)}')

bus.remove('Tina')
print(f'团队成员:{team}\n公交车乘客: {bus}')

运行结果:

 这个例子和下面一个例子一定要好好区分开看,这个例子中bus移除元素tina,但团队中仍然有该成员,和下面这个例子不同,一定要记住。

 

复制代码
l1= [3,[66,55,44], (7,8,9)]
l2 = list(l1)
l3 = l1

print("l2 is l1:", l2 is l1)
print('l3 is l1:', l3 is l1)

print(f'''      l1[0] address: {id(l1[0])}, l2[0] address:{id(l2[0])} 
      l1[1] address: {id(l1[1])}, l2[1] address:{id(l2[1])}
      l1[2] address: {id(l1[2])}, l2[2] address:{id(l2[2])}''')
      
      
 
l1.append(100)
l1[1].remove(55)

print("\nl1追加元素100对l2没有影响,但移除l1[1]中的元素55对l2有影响,因为它们指向同一个地址:")
print(f' l1 content:{l1}\n l2 content:{l2}')

print("\nl2[1]添加[33,22]:")
l2[1] += [33,22]
print(f' l1 content:{l1}\n l2 content:{l2}')

#l1和l2,谁对[1]中的列表进行修改,相应的都会在另一方看到对应的修改



print("\nl2[2] += (10,11)修改后:")
l2[2] += (10,11)
print(f' l1 content:{l1}\n l2 content:{l2}')

print("\n元组使用+=会创建一个新元组,可以看到现在l1[2]和l2[2]位置上不是同一个对象:")
print(f'''      l1[0] address: {id(l1[0])}, l2[0] address:{id(l2[0])} 
      l1[1] address: {id(l1[1])}, l2[1] address:{id(l2[1])}
      l1[2] address: {id(l1[2])}, l2[2] address:{id(l2[2])}''')
复制代码

运行结果:

 

 

复制代码
import copy


class Bus:
    def __init__(self, passengers = None):
        if passengers is None:
            self.passengers = []
        else:
            self.passengers = list(passengers)
            
    
    def pick(self, name):
        self.passengers.append(name)
    
    def drop(self, name):
        self.passengers.remove(name)
        


bus1 = Bus(['Alice', 'Bill', 'Claire', 'David'])
bus2 = copy.copy(bus1)
bus3 = copy.deepcopy(bus1)

print(id(bus1), id(bus2), id(bus3))
print(id(bus1.passengers), id(bus2.passengers), id(bus3.passengers))


bus4 = Bus(['Alice', 'Bill', 'Claire', 'David'])
print(id(bus4), id(bus4.passengers))
复制代码

运行结果:

 

 

 

复制代码
a = ['hello', 'dog', 'cat', 'rain']
b = list(a)
c = a

print("\na和c是指向同一个对象:",id(a), id(c))  #a和c是指向同一个对象: 2256669790144 2256669790144
print("list(a)返回的是副本:", id(b))  #list(a)返回的是副本: 2256670915264

import copy
e = copy.copy(a)
f = copy.deepcopy(a)
print("e和f也是返回的副本:",id(e), id(f))  #e和f也是返回的副本: 2256671477760 2256670915904
复制代码

 

posted @   limalove  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示