笔者在创建二维列表引发的思考!!!
# str1、str2 内容相同,C、D内容相同。str1 和 str2 指向同一个对象, 而 C 和 D 却不指向同一个!!!
>>> str1 = 'apple'
>>> str2 = 'apple'
>>> str1 is str2
True
>>> C = [1,2,3]
>>> D = [1,2,3]
False
# 看起来是两种创建方式,可是他们一样吗???
# 法一:
>>> A = [0] * 3
>>> for i in range(3):
A[i] = [0] * 3
>>> print(A)
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# 法二:
>>> B = [[0] * 3] * 3
>>> print(B)
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# 通过下列例子我们发现!!!二者大有不同!!!
>>> A[0][1] = 3
>>> print(A)
[[0, 3, 0], [0, 0, 0], [0, 0, 0]]
>>> B[0][1] = 3
>>> print(B)
[[0, 3, 0], [0, 3, 0], [0, 3, 0]]
# 验证————分析!!!
>>> A[0] is A[2]
False
# 我们发现通过第22行代码创建的二维列表B: B[0]、B[1]、B[2]竟然指向同一个对象!!!
>>> B[0] is B[2]
True
# 结论: 原来 通过 B = [[0] * 3] * 3 创建二维列表,只是对同一个列表的引用进行了copy,而不是对列表本身进行copy.
# 即重复引用它
浅拷贝
浅拷贝只是拷贝了外层的对象,如果包含嵌套对象那么包含的只是其引用。
>>> x = [[1,2,3],[4,5,6],[7,8,9]]
>>> y = x.copy() # 列表的copy方法
>>> x is y
False # 拷贝了外层,所以外层对象不是同一个。(因为在内存中复制了)
>>> x[2] is y[2]
True # 内层没有拷贝,
# 验证一下
>>> x[1][1] = 0
>>> print(y)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> print(x)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> x[1] = [0,0,0]
>>> print(x)
[[1, 2, 3], [0, 0, 0], [7, 8, 9]]
>>> print(y)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>>
>>> import copy
>>> x = [[1,2,3],[4,5,6],[7,8,9]]
>>> y = copy.copy(x) # copy模块中的copy函数
>>> x[1][1] = 0
>>> print(y)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>> x = [[1,2,3],[4,5,6],[7,8,9]]
这是为什么呢?
深拷贝原来在 x = [[1,2,3],[4,5,6],[7,8,9]]中
可以看成 引用x 指向 对象1
因为对象1中又包含3个列表
so 引用 x 指向 [引用101, 引用102, 引用103]
so 最后 y 指向 x.copy 只是 拷贝了三个引用 ...
拷贝了三个引用即在存储中重新创建(copy)了3个相同引用,他们指向存储中的同一个[[1,2,3],[4,5,6],[7,8,9]]
so 修改[[1,2,3],[4,5,6],[7,8,9]] 在内存的值 ... 你懂的
多维列表内外层全部拷贝!!!
# 深拷贝
>>> y = copy.deepcopy(x)
>>> x[1][1] = 0
>>> print(y)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> print(x)
[[1, 2, 3], [4, 0, 6], [7, 8, 9]]
>>>
结语
既然如此深拷贝如此方便,
那python为什么要默认深拷贝呢?答案就两字————效率
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)