首頁  >  文章  >  後端開發  >  Python中的複製操作及copy模組中的淺拷貝與深拷貝方法

Python中的複製操作及copy模組中的淺拷貝與深拷貝方法

WBOY
WBOY原創
2016-07-22 08:56:371444瀏覽

程式中常常需要複製一個物件, 依思路應該是這樣的

a = [1, 2, 3]
b = a

# [1, 2, 3]
print b 

已經複製好了,但是現在得改一下第一個元素的值把它改成5

b[0] = 5 

# [5, 2, 3]
print b 

# [5, 2, 3]
print a 

我改變了b的第一個元素的值,但是a的值也改變了,這是因為python中的=是引用.a和b指向的是相同的列表,所以改變列表會出現以上的結果.

解決方法是切片操作

a = [1, 2, 3]
b = a[:]
b[0] = 4

# [1, 2, 3]
# [4, 2, 3]
print a
print b

但是在巢狀清單的時候呢,試試看

a = [[1,2,3], 4, 5]
b = a[:]
b[1] = 0 

# [[1,2,3], 4, 5]
# [[1,2,3], 0, 5]
print a
print b

恩!沒什麼問題,在試試嵌套列表元素

a = [[1,2,3], 4, 5]
b = a[:]
b[0][0] = 5

# [[5,2,3], 4, 5]
# [[5,2,3], 4, 5]
print a
print b
b = a[:]

a的值還是改變了,切片複製只對該物件進行拷貝不會對子元素進行拷貝

copy 模組

copy模組用於物件的拷貝操作。這個模組非常簡單,只提供了兩個主要的方法: copy.copy 與 copy.deepcopy ,分別表示淺複製與深複製。什麼是淺複製,什麼是深複製,網路上有一卡車一卡車的資料,這裡不作詳細介紹。複製操作只對複合物件有效。用簡單的例子來分別介紹這兩個方法。

淺複製只複製物件本身,沒有複製該物件所引用的物件。

#coding=gbk
import copy
l1 = [1, 2, [3, 4]]
l2 = copy.copy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2

結果:

[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
[1, 2, [50, 4]]

同樣的程式碼,使用深複製,結果就不一樣:

import copy
l1 = [1, 2, [3, 4]]
l2 = copy.deepcopy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2

結果:

[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]

改變copy的預設行為

定義類別的時候,定義__copy__和__deepcopy__方法,可以改變copy的預設行為。下面是一個簡單的例子:

class CopyObj(object):
  def __repr__(self):
    return "CopyObj"
  
  def __copy__(self):
    return "Hello"
obj = CopyObj()
obj1 = copy.copy(obj)
print obj
print obj1

結果:

CopyObj
Hello
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn