python学习笔记之--深浅拷贝

python中有两种数据类型:一种是可变数据类型,一种是不可变数据类型

不可变数据类型包括(整型及其他数据类型,字符串及元组)

可变数据类型包括(列表,集合,字典,类和类实例)

#=赋值:数据完全共享(如果是可变类型,比如列表,修改其中一个,另一个必定改变;如果是不可变类型,比如字符串,修改了其中一个,另一个并不会变)

赋值内存地址是相同的,所以他们不属于拷贝,只是引用

可变类型例子:

>>> a=[1,2,3,"a",["b","c"]]
>>> b=a
>>> a
[1, 2, 3, 'a', ['b', 'c']]
>>> b
[1, 2, 3, 'a', ['b', 'c']]
>>> id(a)
3101861188616
>>> id(b)
3101861188616

>>> a.append(100)
>>> a
[1, 2, 3, 'a', ['b', 'c'], 100]
>>> b
[1, 2, 3, 'a', ['b', 'c'], 100]
>>> a[4].append('x')
>>> a
[1, 2, 3, 'a', ['b', 'c', 'x'], 100]
>>> b
[1, 2, 3, 'a', ['b', 'c', 'x'], 100]

不可变类型例子:

>>> a='abc'
>>> b=a
>>> a
'abc'
>>> b
'abc'
>>> b='x'
>>> a
'abc'
>>> b
'x'
>>> print(id(a)==id(b))
False

#浅拷贝:数据半共享(只是拷贝原来变量中的不可变数据类型,可变数据类型只是引用)

>>> import copy
>>> a=[1,2,3,"a",["b","c"]]
>>> c=copy.copy(a)
>>> print(type(a),type(a[0]),type(a[4]))
<class 'list'> <class 'int'> <class 'list'>
>>> print(id(a)==id(c))
False
>>> print(id(a[0])==id(c[0]))
True
>>> print(id(a[4])==id(c[4]))    -------当两个可变类型指向同一个内存地址时其中一个改变另一个也会随之改变,反之则不变;两个不可变类型之间改变互不影响
True
>>> c.append('x')
>>> c[4].append("d")
>>> c[0]=100
>>> print(a)
[1, 2, 3, 'a', ['b', 'c', 'd']]   #a里可变类型改变了,不可变类型未改变
>>> print(c)
[100, 2, 3, 'a', ['b', 'c', 'd'], 'x']
>>>

 
 
#深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,形成一个新的对象,虽然与之前的值和内容一模一样,但是它们完完全全的两个对象,互不影响)

>>> import copy
>>> a=[1,2,3,"a",["b","c"]]
>>> d=copy.deepcopy(a)
>>> print(type(a),type(a[0]),type(a[4]))
<class 'list'> <class 'int'> <class 'list'>
>>> print(id(a)==id(d))
False
>>> print(id(a[0])==id(d[0]))
True
>>> print(id(a[4])==id(d[4]))
False
>>> d.append('x')
>>> d[4].append("d")
>>> d[0]=100
>>> print(a)
[1, 2, 3, 'a', ['b', 'c']]    #a里的可变类型和不可变类型都未改变
>>> print(d)
[100, 2, 3, 'a', ['b', 'c', 'd'], 'x']

 
浅拷贝:copy.copy
       不可变类型和可变类型都跟原列表中的地址一样,所以其中一个不可类型改变时另一个不受影响,可变类型因为地址相同一个改变时另一个也随之改变。
深拷贝:copy.deepcopy
       不可变类型的地址是原列表中的地址,可变类型的地址是新生成元素的地址(即独立地址),所以不可变类型之间改变互不影响,可变类型因为内存地址不能也互不影响。
 
 
深层理解例子:
>>> a=["m",[2,3]]
>>> b=copy.copy(a)
>>> a
['m', [2, 3]]
>>> b
['m', [2, 3]]
>>> id(a[0])
3101857249296
>>> id(b[0])   
3101857249296
>>> id(a[1])
3101861179912
>>> id(b[1])
3101861179912---------------#浅拷贝,可变类型和不可变类型地址都跟原列表的一样
>>> c=copy.deepcopy(a)
>>> a
['m', [2, 3]]
>>> c
['m', [2, 3]]
>>> id(a[0])
3101857249296
>>> id(c[0])--------------------#深拷贝,不可变类型地址跟原列表地址一样
3101857249296
>>> id(a[1])
3101861179912
>>> id(c[1])--------------------#深拷贝,可变类型地址跟原列表地址不一样
3101861175240
原文地址:https://www.cnblogs.com/wenm1128/p/11619554.html