1. 程式人生 > >Python中copy和deepcopy的區別,以及程式設計實現deepcopy的功能

Python中copy和deepcopy的區別,以及程式設計實現deepcopy的功能

在python中,有淺複製copy()和深度複製deepcopy(),這兩個的區別我用以
下的例子來說明,例如:
numlist=[[1,2,[3,4,5]],34,"haha",{"name":{"fistname":"孫","lastName":"悟空"}}]
設  numlist1 = copy(numlist),numlist1是numlist經過淺複製後得到的一個列表,
設  numlist2 = deepcopy(numlist),numlist2是numlist經過深度複製後的帶的一個列表
兩者的區別:
假如執行表示式 numlist[0][2] = 6,則上面的三個列表的值如下:
numlist=[[1,2,6],34,"haha",{"name":{"fistname":"孫","lastName":"悟空"}}]

numlist1 = numlist=[[1,2,6],34,"haha",{"name":{"fistname":"孫","lastName":"悟空"}}]
numlist2 = numlist=[[1,2,[3,4,5]],34,"haha",{"name":{"fistname":"孫","lastName":"悟空"}}]
再執行表示式  numlist[3]["name"]="孫大聖" ,三個列表就變成了如下:
numlist=[[1,2,6],34,"haha",{"name":"孫大聖"}]
numlist1 = numlist=[[1,2,6],34,"haha",{"name":"孫大聖"}]

numlist2 = numlist=[[1,2,[3,4,5]],34,"haha",{"name":{"fistname":"孫","lastName":"悟空"}}]

copy()和deepcopy()的區別總結如下:
由淺複製得到的列表,如果列表中含有可變型別的資料,則只要一個列表中的可變型別的資料改變後,另一個表的可變型別的資料也會改變,例如上面的numlist和numlist1而由深度複製得到的列表,如果列表中含有可變型別的資料,則只要一個列表中的可變型別的資料改變後,另一個表的可變型別的資料不會改變,例如上面的numlist和numlist2

編寫程式實現deepcopy:
定義個處理函式 deepcopy(data),data是傳進來的序列,建立一個新的列表listdata,然後遍歷
序列data,如果是int型別或者str型別等不可變型別的資料,直接新增到listdata中,如果是dict(字
典型別的資料),則呼叫copydict(i)函式,因為字典的遍歷跟tuple和list的遍歷不同,所以這裡定義
了一個專門拿來處理字典型別的函式,如果是list(列表)或者tuple(元組)型別的資料,則遞迴調
用deepcopy()函式,直到所有的資料都是不可變型別的資料。


程式碼如下:

#自定義的deepcopy函式
def deepcopy(data):
    #新建的列表
listdata = []
    if len(data)!=1:
        for i in data:
            #如果idict型別的資料,則呼叫字典處理函式copydict()
if isinstance(i,dict):
                dictdata = copydict(i)
                listdata.append(dictdata)
            #如果是元組和列表則遞迴呼叫deepcopy()函式
elif isinstance(i,list) or isinstance(i,tuple):
                listdata1 = deepcopy(i)
                listdata.append(listdata1)
            #其他不可變型別的資料就新增到列表listdataelse:
                listdata.append(i)
    else:
        return data
    return listdata

#字典型別的處理函式
def copydict(data):
    dict1 = {}
    #遍歷字典
for keys,values in data.items():
        #以下的每一步的含義與deepcopy中的相似
if isinstance(values,dict):
            numdict=copydict(values)
            dict1[keys]=numdict
        else:
            value = deepcopy(values)
            dict1[keys]=value
    return dict1

if __name__ == '__main__':
    numlist = [[1, 2, [3, 4, 5]], 34, "number", {"name": {"fistname": "", "lastName": "悟空","listname":[1,2,3]}}]numlist2 = deepcopy(numlist)
    print(id(numlist[0]))
    print(id(numlist2[0]))
    print(numlist2)
    print(numlist)