6

尽管我很喜欢 Python,但参考和 deepcopy 的东西有时会让我感到害怕。

为什么 deepcopy 在这里不起作用:

>>> import copy
>>> a = 2*[2*[0]]
>>> a
[[0, 0], [0, 0]]
>>> b = copy.deepcopy(a)
>>> b[0][0] = 1
>>> b
[[1, 0], [1, 0]]     #should be: [[1, 0], [0, 1]]
>>> 

我正在使用一个 numpy 数组作为我以后需要的工作区。但我真的希望,如果我使用 deepcopy,我就不必再追逐任何无意的引用了。是否还有其他不起作用的陷阱?

4

2 回答 2

15

它不起作用,因为您正在创建一个具有两个对同一数组的引用的数组。

另一种方法是:

[[0]*2 for i in range(2)]

或者更明确的:

[[0 for j in range(2)] for i in range(2)]

这是有效的,因为它在每次迭代时都会创建一个新数组。

是否还有其他不起作用的陷阱?

任何时候你有一个包含引用的数组,你都应该小心。例如[Foo()] * 2不一样[Foo() for i in range(2)]。在第一种情况下,只构造了一个对象,并且数组包含对它的两个引用。在第二种情况下,构造了两个单独的对象。

于 2011-02-01T17:27:17.930 回答
7

它完全按照您的预期工作。

a = 2*[2*[0]]

当您与 相乘[[0,0]]2 *,新列表的两个元素都将指向相同的[0,0]列表。a[0]并且a[1]是同一个列表,因为引用是复制的,而不是数据(这是不可能的)。更改其中一个的第一个元素会更改另一个的第一个元素。

copy.deepcopy正确复制列表,保留唯一对象。

于 2011-02-01T17:32:01.347 回答