Python浅拷贝深拷贝之copy、deepcopy

liftword3个月前 (03-01)技术文章34

笔记记录20221205:


个人总结:

1,两者基本区别不大;

2,在涉及到子对象时候,两者才有区别;

3,在涉及到子对象,且子对象的操作后内存地址没有发生变化(如下方代码:dic1['one'].append(4)),这时才有区别,即复制后的新对象,是copy的会发生变化、是deepcopy的不会发生变化

# 浅拷贝(copy()):拷贝父对象,不会拷贝对象内部的子对象。例子如下:
# 列表举例:li2进行copy了li1,li1变化,li2不会变化:
li1 = [1,2,3]
li2 = li1.copy()
print('li1:',li1,'li2:',li2) # li1: [1, 2, 3] li2: [1, 2, 3]
li1.append(4)
print('li1:',li1,'li2:',li2) # li1: [1, 2, 3, 4] li2: [1, 2, 3]


# 但是在上面的例子中看不出子对象父对象关系,那我们用下面这个例子:
'''
总结:
1,父对象发生了变化,复制后的新对象不会发生变化
2,当父对象没有发生变化,仅仅只是子对象发生了变化:
    2.1,子对象的内存地址没有变化,那么复制后的新对象会发生变化
    2.2,子对象的内存地址有变化,那么复制后的新对象不会发生变化
'''
# 字典举例:
dic1 = {'one':[1,2,3],'two':[4,5,6]}
dic2 = dic1.copy()
# dic1: 2488946315520 {'one': [1, 2, 3], 'two': [4, 5, 6]}
# dic2: 2488946315520 {'one': [1, 2, 3], 'two': [4, 5, 6]},
# dic1和dic2是独立的对象,但是它们的子对象[1,2,3]还是指向统一的对象,内存地址
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)


# 2,当父对象没有发生变化,仅仅只是子对象发生了变化:
    # 2.1,子对象的内存地址没有变化,那么复制后的新对象会发生变化
# 直接append,虽然子对象发生了变化,但是因为2.1:子对象的内存地址没有变化,那么dic2的键one的值,也随之发生改变
dic1['one'].append(4)
# dic1: 2488946315520 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
# dic2: 2488946315520 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)


# 2,当父对象没有发生变化,仅仅只是子对象发生了变化:
#     2.2,子对象的内存地址有变化,那么复制后的新对象不会发生变化
# 直接对字典对象进行操作,对one键进行重新赋值,那么满足2.2:子对象的内存地址有变化,这时dic2不会发生变化
dic1['one'] = [7,8,9]
# dic1: 2043613030208 {'one': [7, 8, 9], 'two': [4, 5, 6]}
# dic2: 2043612942528 {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
print('dic1:',id(dic1['one']),dic1,'dic2:',id(dic2['one']),dic2)


# 1,父对象发生了变化,复制的对象不会发生变化
dic3 = {'one':[1,2,3],'two':[4,5,6]}
dic4 = dic3.copy()
# 直接对字典对象进行操作,新增一个键值对,这时dic2不会发生变化
dic3['three'] = [7,8]
# dic3: {'one': [1, 2, 3], 'two': [4, 5, 6], 'three': [7, 8]}
# dic4: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic3:',dic3,'dic4:',dic4)


# 1,父对象发生了变化,复制的对象不会发生变化
dic5 = {'one':[1,2,3],'two':[4,5,6]}
dic6 = dic5.copy()
dic5.popitem() # 删除最后一个键值对
# dic5: {'one': [1, 2, 3]}
# dic6: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic5:',dic5,'dic6:',dic6)


# 深拷贝(deepcopy()):是copy模块中的方法,完全拷贝了子对象和父对象,例子如下:
# 深度拷贝, dic8完全拷贝了dic7父对象及其子对象,两者是完全独立的
from copy import deepcopy
dic7 = {'one':[1,2,3],'two':[4,5,6]}
dic8 = deepcopy(dic7)
dic7['one'].append(4)
# dic7: {'one': [1, 2, 3, 4], 'two': [4, 5, 6]}
# dic8: {'one': [1, 2, 3], 'two': [4, 5, 6]}
print('dic7:',dic7,'dic8:',dic8)



相关文章

文件备份用Python,照着复制粘贴代码就可以了

引言在日常开发和运维工作中,数据安全尤为重要,定期备份重要文件是防范数据丢失的有效手段之一。本文将详细介绍如何使用Python实现一个简单的定时备份脚本,该脚本可以按照设定周期自动将指定文件夹或文件复...

Python之如何使用Python脚本批量复制一个文件夹下的所有PNG图片

大家好,今天我要与大家分享一个实用的Python脚本,它能帮助你轻松地将一个文件夹中的所有PNG图片批量复制到另一个文件夹。无论是整理电脑文件,还是进行项目备份,这个小工具都能大大提高你的工作效率。以...

使用Python从PDF文件中提取数据_python读取pdf内容转word

前言数据是数据科学中任何分析的关键,大多数分析中最常用的数据集类型是存储在逗号分隔值(csv)表中的干净数据。然而,由于可移植文档格式(pdf)文件是最常用的文件格式之一,因此每个数据科学家都应该了解...

Python之鸭子类型:魔术方法&深拷贝和浅拷贝

引言在Python中,一切皆对象。虽然都是对象,又可以分为可变对象和不可变对象。我们可以通过赋值操作,实现一个看似拷贝对象的作用,但是,由于“变量的标签模型”,我们知道赋值实现的拷贝,本质上只是对同一...

这篇文章教会你打包Python程序_python 怎么打包

编程派微信号:codingpy本文作者为 Gigi Sayfan ,发布在知名编程学习网站 Tutsplus。是 Python 翻译组最新发布的一篇译文,希望对大家学习如何打包有帮助。译者为 Chen...