- 浅拷贝,拷贝完后,地址一样:
In [75]: a = [11,22,33]
In [76]: b = a
In [77]: id(a)
Out[77]: 139742502804296
In [78]: id(b)
Out[78]: 139742502804296
Python中都是浅拷贝,内容共享。你修改你的,我的也跟着变了。
-
深拷贝,可以通过
copy
模块进行:
In [82]: import copy
In [83]: a = [11,22,33]
In [84]: b = copy.deepcopy(a)
In [86]: id(a)
Out[86]: 139742502803976
In [87]: id(b)
Out[87]: 139742502835464
复制一份给你,但内容不共享。你以后修改了,与我的那份无关。
copy.deepcopy()
和 copy.copy()
都只会对可变类型进行深拷贝。
不同的是:
deepcopy()
是会递归判断的深拷贝:如果下一层是可变类型,那么下一层以及下一层之前的层都进行深拷贝。
In [93]: a = [11,22,33]
In [94]: b = [44,55,66]
In [95]: c = [a,b] #list
In [96]: d = copy.deepcopy(c)
In [97]: a.append(44)
In [98]: c
Out[98]: [[11, 22, 33, 44], [44, 55, 66]]
In [99]: d
Out[99]: [[11, 22, 33], [44, 55, 66]]
In [140]: a = [11,22,33]
In [141]: b = [44,55,66]
In [142]: c = (a,b) #元祖 递归判断
In [143]: d = copy.deepcopy(c)
In [144]: c is d
Out[144]: False
In [145]: a.append(44)
In [146]: c
Out[146]: [[11, 22, 33, 44], [44, 55, 66]]
In [147]: d
Out[147]: [[11, 22, 33], [44, 55, 66]]
In [134]: a = (11,22,33)
In [135]: b = (44,55,66)
In [136]: c = (a,b) #不可变
In [137]: d = copy.deepcopy(c)
In [138]: c is d
Out[138]: True
In [131]: c = (11,22) #不可变
In [132]: d = copy.deepcopy(c)
In [133]: c is d
Out[133]: True
copy.copy()
是非递归深拷贝,只考虑第一层:如果第一层是可变类型,则只对第一层深拷贝;如果第一层不是可变类型,则进行浅拷贝。
In [106]: a = [11,22,33]
In [107]: b = [44,55,66]
In [108]: c = [a,b] #list 不进行递归判断
In [109]: d = copy.copy(c)
In [110]: id(c)
Out[110]: 139742502712840
In [111]: id(d)
Out[111]: 139742502645512
In [112]: a.append(44)
In [113]: c
Out[113]: [[11, 22, 33, 44], [44, 55, 66]]
In [114]: d
Out[114]: [[11, 22, 33, 44], [44, 55, 66]]
In [146]: a = [11,22,33]
In [147]: b = [44,55,66]
In [148]: c = (a,b) #元祖 不进行递归判断
In [149]: d = copy.copy(c)
In [150]: c is d
Out[150]: True
其它语言专场:
其它语言,例如: c、Java :
只会对不可变类型进行深拷贝,可变类型都是浅拷贝。
函数传参的时候可以看出来。
package xxx;
import java.util.List;
import java.util.ArrayList;
class A{
String name = "abc";
@Override
public String toString() {
return "A [name=" + name + "]";
}
}
public class DeepCopy_ShallowCopy {
static void changeA(A a){
a.name += "222";
System.out.println(a);
}
static void changeD(List d){
d.add("222");
System.out.println(d);
}
static void changeB(String b){
b += "222";
System.out.println(b);
}
static void changeC(int c){
c+=222;
System.out.println(c);
}
public static void main(String[] args) {
A a = new A();
List d = new ArrayList();
d.add("aa");
d.add("bb");
d.add("cc");
String b = "bbb";
int c = 333;
System.out.println("函数里:");
changeA(a);
changeD(d);
changeB(b);
changeC(c);
System.out.println("-------------------");
System.out.println("函数外:");
System.out.println(a);
System.out.println(d);
System.out.println(b);
System.out.println(c);
}
}
函数外,值变了的是浅拷贝,内容共享。
函数外,值没变的是深拷贝,函数里操纵的是另一片内存。
函数里:
A [name=abc222]
[aa, bb, cc, 222]
bbb222
555
-------------------
函数外:
A [name=abc222] #变了
[aa, bb, cc, 222] #变了
bbb #没变
333 #没变
网友评论