本文主要介绍Python中,使用copy()或dict()方法对字典(dict)对象浅拷贝,和使用deepcopy()方法对字典(dict)对象深拷贝的方法,以及相关的示例代码。

1、Python 深拷贝与浅拷贝

深拷贝和浅拷贝都是对Python中对象的复制,占用不同的内存空间。深拷贝会完全拷贝父对象及父对象内部的子对象,而浅拷贝会拷贝父对象,但不会拷贝父对象内部的子对象。

浅拷贝会出现的问题就是,有可能拷贝后的对象中内部的子象(例如,字典value是一个类对象或列表,就是内部的子对象),当修改这个子对象时,父对象中内部的子对象,也会被修改,浅拷贝会存在这个问题,因为同一个对象,深拷贝就不会存在这个问题。

2、使用copy()或dict()字典浅拷贝

dic = {"C":1,"Java":2,"Python":4,"CJavaPy":5}
d1 = dict(dic)#浅拷贝
print(d1)
d2 = dic.copy() #浅拷贝
print(d2)

3、使用deepcopy()字典深拷贝

from copy import deepcopy
dic = {"C":1,"Java":2,"Python":4,"CJavaPy":5}
d1 = deepcopy(dic) #深拷贝
print(d1) 

4、判断深拷贝和浅拷贝

根据深浅拷贝后父对象内部子对象,和拷贝后的子对象内部子对象的区别,来判断是深拷贝还是浅拷贝,代码如下,

1)内部子对象是列表

示例中子对象使用的列表,其它数据集合类型(如,元组,字典,集合等),和列表基本相同。

from copy import deepcopy dic = {"C":[1,1,1],"Java":[2,2,2],"Python":[4,4,4],"CJavaPy":[5,5,5]} d1 = deepcopy(dic) #深拷贝 print("d1=",d1) d2 = dic.copy() #浅拷贝 print("d2=",d2) print("--------深拷贝修改子对象--------") #对字典内部子对象列表修改 d1["C"].append(111) d1["CJavaPy"].append(111) print("子对象修改后d1:\n ",d1) print("深拷贝的父对象:\n ",dic) #父对象没有修改 print("--------浅拷贝修改子对象--------") d2["C"].append(222) d2["CJavaPy"].append(222) print("子对象修改后d2:\n ",d2) print("浅拷贝的父对象:\n ",dic) #父对象被修改了

2)字典内部子对象是类对象

from copy import deepcopy

class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)
    
dic = {"C":Person("c", "c"),"Java":Person("java", "java"),"Python":Person("python", "python"),"CJavaPy":Person("cjavapy", "cjavapy")}

d1 = deepcopy(dic) #深拷贝
print("d1=",d1) 
d2 = dic.copy()    #浅拷贝
print("d2=",d2)
print("--------深拷贝修改子对象--------")
#对字典内部子对象列表修改
d1["C"].firstname = "深拷贝"
d1["CJavaPy"].lastname = "深拷贝"
print("子对象修改后d1[\"C\"]:")
d1["C"].printname()
print("深拷贝的父对象中d1[\"C\"]:")       #父对象没有修改
dic["C"].printname()
print("子对象修改后d1[\"CJavaPy\"]:")
d1["CJavaPy"].printname()
print("深拷贝的父对象中d1[\"CJavaPy\"]:") #父对象没有修改
dic["CJavaPy"].printname()
print("--------浅拷贝修改子对象--------")
d2["C"].firstname = "浅拷贝"
d2["CJavaPy"].lastname = "浅拷贝"
print("子对象修改后d2[\"C\"]:")
d2["C"].printname()
print("深拷贝的父对象中d2[\"C\"]:")#
dic["C"].printname()      #父对象被修改了
print("子对象修改后d2[\"CJavaPy\"]:")
d2["CJavaPy"].printname()
print("深拷贝的父对象中d2[\"CJavaPy\"]:")#
dic["CJavaPy"].printname() #父对象被修改了

推荐文档