容桂网站制作动态,个性化网站模板,新网站如何做百度收录,怎么看网站源码用什么做的今天在写一个小程序的时候用到了2维数组, 顺手就写成了[[0.0]*length]*length, 结果为了这个小错,调试了半个多小时, 其实之前对与浅复制和深复制已经做过学习和总结, 但真正编程用到这些知识时还是掉入了陷阱中. 所以在此做进一步的总结: 本文通过几个实例来说明Python中list的… 今天在写一个小程序的时候用到了2维数组, 顺手就写成了[[0.0]*length]*length, 结果为了这个小错,调试了半个多小时, 其实之前对与浅复制和深复制已经做过学习和总结, 但真正编程用到这些知识时还是掉入了陷阱中. 所以在此做进一步的总结: 本文通过几个实例来说明Python中list的深复制和浅复制: a [[]] * 10a
[[], [], [], [], [], [], [], [], [], []]a[0][0] 10 #NO WAY
Traceback (most recent call last):File stdin, line 1, in module
IndexError: list assignment index out of rangea[0].append(1)a
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]] a[0].append(1)后, 如果a的输出结果让你感到有些困惑,你可以参考这里(原因是Python中的*运算采用的是浅复制). 同样的道理,下面的代码我们应该都能够理解: a[3].append(9)a
[[1, 9], [1, 9], [1, 9], [1, 9], [1, 9], [1, 9], [1, 9], [1, 9], [1, 9], [1, 9]]a[2][1] 3a
[[1, 3], [1, 3], [1, 3], [1, 3], [1, 3], [1, 3], [1, 3], [1, 3], [1, 3], [1, 3]] 让我们一起来分析一下: 对于a(理解为一个2维数组)中的每一个元素都是一个list(理解为一个1维数组), 但我们需要注意的是a的每一个元素 a[0],a[1],a[2]...指向的是同一段内存区域(浅复制),所以更改(修改值或添加值)任何一个元素(a[0]或a[1]...a[9])都会直接影 响到其它的元素. 如何验证a中的每一个元素a[0], a[1],...,a[9]指向同一段内存区域? 可以通过id方法来验证: id.__doc__
id(object) - integerReturn the identity of an object. This is guaranteed to be unique amongsimultaneously existing objects. (Hint: its the objects memory address.) a [[]]*10a
[[], [], [], [], [], [], [], [], [], []]id(a[0])
3071938316Lid(a[1])
3071938316La[0].append(1)a
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]id(a[0])
3071938316Lid(a[1])
3071938316L注意虽然a的每一个元素a[0],a[1],a[2]...指向的是同一段内存区域但a中的各个元素是独立的元素他们相同但不同一 也就是说删除掉任何一个数据对其他的数据没有任何影响 a [[]] * 10a
[[], [], [], [], [], [], [], [], [], []]a[0].append(1)a
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]len(a)
10del(a[2])a
[[1], [1], [1], [1], [1], [1], [1], [1], [1]]len(a)
9 那么应该怎么实现深复制呢其实在前面提到的文章中已经介绍了这一方法: c [[] for i in range(10)]c
[[], [], [], [], [], [], [], [], [], []]c[0].append(3)c
[[3], [], [], [], [], [], [], [], [], []]至此, 我觉得还有一点需要说明: 一定要理解*操作的对象是谁, 例如: [2]*10得到[2, 2, 2, 2, 2, 2, 2, 2, 2, 2], *10操作的对象是[]中的2, 也就是说*10操 作使list中的元素2复制10次. 同理[[]]*10得到[[], [], [], [], [], [], [], [], [], []],*10操作的对象是[]中的[], 也就是说*10 操作使list中的元素[]浅复制10次, 这10个空list指向内存中相同的区域(参见上面用id验证部分). 下面用2段代码作为对比列出来, 便于查看: a [2] * 10a
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]id(a[0])
164067492id(a[1])
164067492a[0] 1 #NOTEid(a[0]) #NOTE
164067504id(a[1])
164067492b [[]] * 10b
[[], [], [], [], [], [], [], [], [], []]id(b[0])
3072965964Lid(b[1])
3072965964Lb[0].append(10)id(b[0])
3072965964Lid(b[1])
3072965964Lb
[[10], [10], [10], [10], [10], [10], [10], [10], [10], [10]]b[0][0] 1b
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]id(b[0])
3072965964Lid(b[1])
3072965964Lb[0] [10]b
[[10], [1], [1], [1], [1], [1], [1], [1], [1], [1]]id(b[1])
3072965964Lid(b[0])
3072965996L转载于:https://www.cnblogs.com/lxw0109/p/shallow-copy-and-deep-copy.html