Python复制一个列表的列表

13 浏览
0 Comments

Python复制一个列表的列表

我正在使用Python 3.4.1版本。

对于一个单一的列表 a=[1,2],如果我复制它,b = a.copy(),当我改变b中的项目时,a中的项目不会改变。

然而,当我定义一个列表的列表(实际上是一个矩阵)a = [[1,2],[3,4]],当我赋值b = a.copy()时,我对列表b所做的实际上影响了a

我查看了它们的地址,它们是不同的。

有人可以告诉我为什么吗?

附注:我做的是 b[0][0] = x,而a中的项目也被改变了。

0
0 Comments

问题的原因是代码中使用的赋值操作(b = a)只是将b指向了a所指向的对象,而并没有创建一个新的列表对象。这意味着当修改b时,a也会发生相同的修改。这不是一个正确的解决方法,因为我们希望创建一个新的列表对象以便独立地进行修改。

解决方法是使用列表的拷贝方法来创建一个新的列表对象。以下是两种常见的拷贝方法:

1. 使用切片操作符([:])进行拷贝:

b = a[:]

示例:

>>> a = [1, 2, 3]
>>> b = a[:]
>>> b.append(4)
>>> b
[1, 2, 3, 4]
>>> a
[1, 2, 3]

2. 使用列表的copy()方法进行拷贝:

b = a.copy()

示例:

>>> a = [1, 2, 3]
>>> b = a.copy()
>>> b.append(4)
>>> b
[1, 2, 3, 4]
>>> a
[1, 2, 3]

使用这些方法,我们可以创建一个新的列表对象并进行独立的修改,而不会影响原始列表对象。

0
0 Comments

问题的出现原因是在Python中复制一个列表的列表时,使用浅拷贝方法会导致复制的列表仍然包含对原始对象的引用。这会导致对复制的列表进行修改时,原始列表也会被修改。

解决方法是使用列表解析或使用copy模块中的方法进行深拷贝。列表解析的方法是通过创建新的列表,并使用切片操作将原始列表中的每个子列表复制到新列表中。这样可以确保新列表中的子列表是独立的,对其进行修改不会影响原始列表。

另一种方法是使用copy.deepcopy()方法进行深拷贝。这个方法会递归地复制所有的对象,包括子列表中的对象,从而创建一个完全独立的副本。

以下是使用列表解析和copy.deepcopy()方法进行复制的示例代码:

使用列表解析的方法:

new_list = [x[:] for x in old_list]

使用copy.deepcopy()方法的方法:

import copy
new_list = copy.deepcopy(old_list)

通过使用上述方法,可以确保复制的列表是完全独立的,对其进行任何修改都不会影响原始列表。

0
0 Comments

Python中的copy模块提供了浅拷贝和深拷贝的功能。浅拷贝适用于复合对象(包含其他对象的对象,如列表或类实例)。它构建一个新的复合对象,并在可能的情况下将原始对象中的引用插入其中。而深拷贝则递归地构建一个新的复合对象,并在其中插入原始对象的副本。

当使用copy.copy()进行拷贝时,默认进行的是浅拷贝。这意味着对于列表的列表的情况,你将获得一个新的外部列表副本,但它的元素仍然是原始内部列表。相反,你应该使用copy.deepcopy(),它将创建外部和内部列表的新副本。

之所以在使用copy([1,2])的示例中没有注意到这一点,是因为像int这样的基本类型是不可变的,无法在不创建新实例的情况下更改它们的值。如果列表的内容是可变对象(如列表或具有可变成员的任何用户定义对象),那么对这些对象的任何修改都将在列表的两个副本中都可见。

关于拷贝还有一个问题,可以通过简单的方法获得类的拷贝吗?比如树类,可以使用简单的方法获得树对象t1的副本吗?

是的,你可以在任何定义了__copy____deepcopy__方法的对象上使用copy模块。具体细节可以参考原始回答中的链接文档。不过,遗憾的是,Python中没有像C++等语言中那样的“预定义”拷贝操作(对于任何非平凡类,C++的自动生成的拷贝构造函数通常是错误的)。

你可以在pythontutor.com上检查在使用copy方法时发生了什么。你可以在那里看到所有指针的可视化。

0