1、赋值操作:“=”
1)对str操作:类推不可变元组,不可变数字
a = "hello"
b = "hello"
c = a
result = []
result_1 = []
for x in [a, b, c]:
result.append(id(x))
result_1.append(x)
print(result) # [31175712, 31175712, 31175712]
print(result_1) # ['hello', 'hello', 'hello']
a = "world"
result_2 = []
result_3 = []
for x in [a, b, c]:
result_2.append(id(x))
result_3.append(x)
print(result_2) # [35621384, 31175712, 31175712]
print(result_3) # ['world', 'hello', 'hello']
解释:
(1)前提:str是不可变的
(2)系统先给一个变量或者对象(这里是'hello')分配了内存,然后再将地址赋给a, b, c。所以它们的地址是相同的。
(3)str的不可变性,a要重新赋值则需重新开辟内存空间,所以a的值改变,a指向的地址改变。b, c由于'hello'的不变性,不会发生改变。
2)对list操作:类推字典
a = ['hello',"world"]
b = ['hello',"world"]
c = a
result = []
result_1 = []
for x in [a, b, c]:
result.append(id(x))
result_1.append(x)
print(result) # [35871624, 35871880, 35871624]
print(result_1) # [['hello', 'world'], ['hello', 'world'], ['hello', 'world']]
a[0] = "world"
result_2 = []
result_3 = []
for x in [a, b, c]:
result_2.append(id(x))
result_3.append(x)
print(result_2) # [35871624, 35871880, 35871624]
print(result_3) # [['world', 'world'], ['hello', 'world'], ['world', 'world']]
解释:
(1)前提:list是可变的
(2)系统需要给'hello'分配两个地址,分别让a,b指向,同时c也跟a相同的指向。
(3)由于list的可变性,所以修改list的值不需要另外开辟空间,只需修改原地址的值。所以a, c地址均不变,但是值改变;b的地址和值均不变。
2、浅拷贝及深拷贝
import copy
a = [1, 2, 3, 4, ['a', 'b']] # 原始对象
b = a # 赋值,传对象的引用
c = copy.copy(a) # 对象拷贝,浅拷贝
d = copy.deepcopy(a) # 对象拷贝,深拷贝
a.append(5) # 修改对象a
a[4].append('c') # 修改对象a中的['a', 'b']数组对象
print("a===",a)
print("b===",b)
print("c===",c)
print("d===",d)
结果:
a=== [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b=== [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c=== [1, 2, 3, 4, ['a', 'b', 'c']]
d=== [1, 2, 3, 4, ['a', 'b']]
注意:
1)浅拷贝:只拷贝父对象,不会拷贝对象的内部的子对象
2)深拷贝:拷贝对象及其子对象
import copy
a = [1, 2, [3,4]]
print('列表[1,2,[3,4]]的地址:%s\n数值1的地址:%s\n数值2的地址:%s\n子列表[3,4]的地址:%s\n数值3的地址:%s\n数值4的地址:%s\n'%(id([1,2,[3,4]]),id(1), id(2), id([3,4]), id(3), id(4)))
print('a的地址:%s\na[0]的地址:%s\na[1]的地址:%s\na[2]的地址:%s\na[2][0]的地址:%s\na[2][1]的地址:%s\n'%(id(a),id(a[0]),id(a[1]),id(a[2]),id(a[2][0]),id(a[2][1])))
b = a
print('b的地址:%s\nb[0]的地址:%s\nb[1]的地址:%s\nb[2]的地址:%s\nb[2][0]的地址:%s\nb[2][1]的地址:%s\n'%(id(b),id(b[0]),id(b[1]),id(b[2]),id(b[2][0]),id(b[2][1])))
c = a.copy()
print('c的地址:%s\nc[0]的地址:%s\nc[1]的地址:%s\nc[2]的地址:%s\nc[2][0]的地址:%s\nc[2][1]的地址:%s\n'%(id(c),id(c[0]),id(c[1]),id(c[2]),id(c[2][0]),id(c[2][1])))
d = copy.deepcopy(a)
print('d的地址:%s\nd[0]的地址:%s\nd[1]的地址:%s\nd[2]的地址:%s\nd[2][0]的地址:%s\nd[2][1]的地址:%s\n'%(id(d),id(d[0]),id(d[1]),id(d[2]),id(d[2][0]),id(d[2][1])))
结果:
列表[1,2,[3,4]]的地址:36176008
数值1的地址:504589328
数值2的地址:504589360
子列表[3,4]的地址:36176008
数值3的地址:504589392
数值4的地址:504589424
a的地址:36072456
a[0]的地址:504589328
a[1]的地址:504589360
a[2]的地址:36072200
a[2][0]的地址:504589392
a[2][1]的地址:504589424
b的地址:36072456
b[0]的地址:504589328
b[1]的地址:504589360
b[2]的地址:36072200
b[2][0]的地址:504589392
b[2][1]的地址:504589424
c的地址:36176008
c[0]的地址:504589328
c[1]的地址:504589360
c[2]的地址:36072200
c[2][0]的地址:504589392
c[2][1]的地址:504589424
d的地址:36176072
d[0]的地址:504589328
d[1]的地址:504589360
d[2]的地址:36175944
d[2][0]的地址:504589392
d[2][1]的地址:504589424