python列表列表取消链接对象

时间:2016-07-24 18:02:02

标签: python python-3.x

我有两个列表,我合并为一个列表。后来我想制作这个列表的副本,这样我就可以对第二个列表进行一些操作,而不会影响我的第一个列表。我的理解是如果你使用这个[:]它应该取消链接列表并在独立的内存位置制作列表的第二个副本。我的问题是我没有看到我的这种情况的工作。我也尝试过使用list命令,但结果是一样的。

a = ['a','b','c']
b = ['1','2','3']
c = [a[:],b[:]] # list of list

d = c[:] # want to create copy of the list of list so I can remove last item
for item in d:
    del item[-1]

# this is what I am getting returned.
In [286]: c
Out[286]: 
[['a', 'b'], ['1', '2']]

In [287]: d
Out[287]: 
[['a', 'b'], ['1', '2']]

2 个答案:

答案 0 :(得分:2)

[:]只能制作一份浅色副本。也就是说,它复制列表本身,但不复制列表中的项目。您应该使用copy.deepcopy

import copy
d = copy.deepcopy(c)

将列表视为具有指向对象的指针。现在你的变量是一个指向列表的指针。 [:]所做的是创建一个具有相同精确指针的全新列表。 copy.deepcopy复制对象中的所有属性/引用,以及这些属性/引用中的属性/引用。

答案 1 :(得分:0)

你在Python中遇到了浅层和深层复制的概念。

当列表结构没有任何子列表时,切片运算符很有效。

list1 = ['a', 'b', 'c', 'd']
list2 = list1[:]
list2[1] = 'x'
print list1
['a', 'b', 'c', 'd']
print list2
['a', 'x', 'c', 'd']

这似乎工作正常,但只要列表包含子列表,我们就会遇到同样的困难,即只是指向子列表的指针。

list1 = ['a', 'b', ['ab', 'ba']]
list2 = list1[:]

如果为两个列表之一的元素分配新值,则不会产生副作用,但是,如果更改子列表中的某个元素,则会出现同样的问题。

这类似于修改c中子列表a和b的内容。

要避免此问题,您必须使用deepcopy来创建列表的深层检查。

这可以按照以下方式完成:

from copy import deepcopy

list1 = ['a', 'b', ['ab', 'ba']]
list2 = deepcopy(list1)