(python)不可变对象与可变对象的深拷贝与浅拷贝区分

news/2024/7/19 11:07:20 标签: python, 列表, 字符串

python_0">(python)区分深拷贝与浅拷贝

当我们在对不可变对象与可变对象进行拷贝操作时会有细微的区别,下面我以自己测试的结果来展开分析它们之间的细微区别。
在(python)中可变对象有:
字典,列表,集合,自定义的对象等;
不可变对象有:
数字,字符串,元祖,function等;
测试的重点:拷贝后a(源对象)与b(拷贝后的对象)地址是共享还是独立
首先对可变对象list进行测试:

python">#测试列表浅拷贝与深拷贝
import copy

def textCopy():
    '''测试浅拷贝'''
    #不拷贝子对象的内容,只拷贝了子对象的引用
    a=[10,20,[5,6]]
    b=copy.copy(a)

    print("a",a)
    print("b",b)
    print("浅拷贝......")
    print("a",a)
    print("b",b)
    print("a引用的对象的地址{0}".format(id(a)))
    print("b引用的对象的地址{0}".format(id(b)))
    print("a[2]引用的对象的地址{0}".format(id(a[2])))
    print("b[2]引用的对象的地址{0}".format(id(b[2])))
    print("a[0]引用的对象的地址{0}".format(id(a[0])))
    print("b[0]引用的对象的地址{0}".format(id(b[0])))
    print("a is b:",a is b)
    print("a[2] is b[2]:",a[2] is b[2])
textCopy()


def textDeepCopy():
    '''测试深拷贝'''
    #会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象
    a=[10,20,[5,6]]
    b=copy.deepcopy(a)
    print('a',a)
    print('b',b)
    print("深拷贝......")
    print('a',a)
    print('b',b)
    print("a引用的对象的地址{0}".format(id(a)))
    print("b引用的对象的地址{0}".format(id(b)))
    print("a[2]引用的对象的地址{0}".format(id(a[2])))
    print("b[2]引用的对象的地址{0}".format(id(b[2])))
    print("a[0]引用的对象的地址{0}".format(id(a[0])))
    print("b[0]引用的对象的地址{0}".format(id(b[0])))
    print("a is b:", a is b)
    print("a[2] is b[2]:",a[2] is b[2])
print("*"*20)
textDeepCopy()

在这里插入图片描述
在这里插入图片描述
总结一下:
1.列表浅拷贝后a,b是独立地址,但是a和b里面的可变对象是共享地址
2.列表深拷贝后a,b是独立地址,且a和b里面的可变对象也是独立地址

列表的浅拷贝经历了这样一个过程:
在这里插入图片描述

列表的深拷贝:
在这里插入图片描述
对不可变元祖进行测试

python">#测试元祖的深浅拷贝
import copy

def textCopy():
    '''测试浅拷贝'''
    #不拷贝子对象的内容,只拷贝了子对象的引用
    a=(10,20,[5,6])
    b=copy.copy(a)

    print("a",a)
    print("b",b)
    print("浅拷贝......")
    print("a",a)
    print("b",b)
    print("a引用的对象的地址{0}".format(id(a)))
    print("b引用的对象的地址{0}".format(id(b)))
    print("a[2]引用的对象的地址{0}".format(id(a[2])))
    print("b[2]引用的对象的地址{0}".format(id(b[2])))
    print("a[0]引用的对象的地址{0}".format(id(a[0])))
    print("b[0]引用的对象的地址{0}".format(id(b[0])))
    print("a is b:",a is b)
    print("a[2] is b[2]:",a[2] is b[2])
textCopy()


def textDeepCopy():
    '''测试深拷贝'''
    #会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象
    a=(10,20,[5,6])
    b=copy.deepcopy(a)
    print('a',a)
    print('b',b)
    print("深拷贝......")
    print('a',a)
    print('b',b)
    print("a引用的对象的地址{0}".format(id(a)))
    print("b引用的对象的地址{0}".format(id(b)))
    print("a[2]引用的对象的地址{0}".format(id(a[2])))
    print("b[2]引用的对象的地址{0}".format(id(b[2])))
    print("a[0]引用的对象的地址{0}".format(id(a[0])))
    print("b[0]引用的对象的地址{0}".format(id(b[0])))
    print("a is b:", a is b)
    print("a[2] is b[2]:",a[2] is b[2])
print("*"*20)
textDeepCopy()

浅拷贝运行结果:
在这里插入图片描述
深拷贝运行结果:
在这里插入图片描述
总结一下:
1.元祖浅拷贝后a,b共享地址,且a和b里面的可变对象也是共享地址
2.元祖深拷贝后a,b是独立地址,且a和b里面的可变对象也是独立地址

浅拷贝过程:
在这里插入图片描述
深拷贝过程:
在这里插入图片描述

对不可变对象数字和字符串测试
这里数字和字符串测试结果相同,我就以字符串为列

python">#测试不可变对象数字及字符串的浅拷贝和深拷贝
import copy
def shuzicopy():
    '''测试字符串浅拷贝'''
    a='jqwdko'
    b=copy.copy(a)
    print(id(a))
    print(id(b))
    print(a is b)
shuzicopy()
def shuzideepcopy():
    '''测试字符串深拷贝'''
    a='jqwdko'
    b=copy.deepcopy(a)
    print(id(a))
    print(id(b))
    print(a is b)

print("_"*10)
shuzideepcopy()

运行结果:
在这里插入图片描述
总结:字符串与数字的深浅拷贝的效果一样:
拷贝后a,b都是共享地址


http://www.niftyadmin.cn/n/1465484.html

相关文章

idea里把选中的变为大写或小写快捷键

ctrlshiftu 如果选中的是大写,用这个快捷键会变为小写,反之则变为大写。 也就是说转换为大写和小写的快捷键是同一个。

[leetCode]279. 完全平方数

题目 链接:https://leetcode-cn.com/problems/perfect-squares 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。 示例 1: 输入: n 12 输出: 3 解释: 12…

C语言中的clock()函数,计时函数

clock():捕捉从程序开始运行到clock()被调用时所消耗的时间。这个时间单位是clock tick,即“时钟打点”。 常数CLK_TCK:机器时钟每秒所走的时钟打点数。 以下面代码为例来解释clock()函数的用法 #include<stdio.h> #include<time.h> //包含time文件clock_t sta…

n阶行列式相乘

n阶行列式相乘 关于行列式相乘 代码如下 #n阶行列式相乘&#xff08;同阶&#xff09;在实际中用的不是特变多&#xff0c;不如直接算n阶行列式 #无特殊情况处理 #N1表示第一个行列式 #M1表示第二个行列式 class Solution(object):def Ride(self):Ninput(输入行列式1,按行输入…

[leetCodr]402. 移掉K位数字

题目 链接&#xff1a;https://leetcode-cn.com/problems/remove-k-digits 给定一个以字符串表示的非负整数 num&#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的数字最小。 注意: num 的长度小于 10002 且 ≥ k。 num 不会包含任何前导零。 示例 1 : 输入: num …

开发环境pycharm虚拟环境工具的使用

开发环境pycharm虚拟环境工具的使用 虚拟环境的安装 通过命令来安装pycharm的虚拟环境 pip install virtualenv 安装过程中如果出现error信息&#xff0c;可以尝试切换数据源下载 pip install virtualenv -i https://pypi.tuna.tsinghua.edu.cn/simple/ 安装好后就可以创建虚拟…

[leetCode]695. 岛屿的最大面积

题目 链接&#xff1a;https://leetcode-cn.com/problems/max-area-of-island 给定一个包含了一些 0 和 1 的非空二维数组 grid 。 一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的…