2012-06-23 30 views
0

我正在加载变量'x'中的二维文件“data.imputation”。变量'y''x'的副本。我从'y'(y是2D)弹出第一个数组。为什么变化反映在x? (从'x'第一阵列也被弹出)在python中复制数组并操作其中一个

ip = open('data.meanimputation','r') 
x = pickle.load(ip) 
y = x 
y.pop(0) 

在开始时,len(x) == len(y)。即使在y.pop(0),len(x) == len(y)之后。这是为什么?我该如何避免它?

回答

2

使用y = x[:]而不是y = xy = x表示yx现在都指向同一个对象。

看看这个例子:

>>> x=[1,2,3,4] 
>>> y=x 
>>> y is x 
True   # it means both y and x are just references to a same object [1,2,3,4], so changing either of y or x will affect [1,2,3,4] 
>>> y=x[:]  # this makes a copy of x and assigns that copy to y, 
>>> y is x  # y & x now point to different object, so changing one will not affect the other. 
False 

如果x是一个列表,列表的名单,然后[:]是没有用的:

>>> x= [[1,2],[4,5]] 
>>> y=x[:] #it makes a shallow copy,i.e if the objects inside it are mutable then it just copies their reference to the y 
>>> y is x 
False   # now though y and x are not same object but the object contained in them are same 
>>> y[0].append(99) 
>>> x 
[[1, 2, 99], [4, 5]] 
>>> y 
[[1, 2, 99], [4, 5]] 
>>> y[0] is x[0] 
True #see both point to the same object 

在这种情况下,你应该使用copy模块的deepcopy()函数,它使对象的非浅层副本。

+0

谢谢。有用。你能解释一下发生了什么吗?有什么区别? –

+0

@ lostboy_19我在答案中添加了解释。 –

+0

y = list(x)更容易理解与y = x相同的语法[:] –

1

y = x不会复制任何内容。它将名称y绑定到x已提及的相同对象。分配给裸名称从不复制Python中的任何内容。

如果你想复制一个对象,你需要明确地复制它,使用任何可用于你要复制的对象的方法。你不会说什么样的对象x是,所以没有办法说出你可以如何复制它,但copy模块提供了一些适用于多种类型的函数。另见this answer

+0

因此y = x.copy()应该工作吗? –

+0

这取决于'x'是什么类型的对象。如果'x'提供了这样一种方法(比如Python字典),它就会工作。你也可以尝试'import copy'然后'y = copy.copy(x)'。但是,如果将x设置为以这种方式复制,那也只能起作用。 Python中没有通用的方法来“复制任何东西”;你需要知道你正在复制什么样的东西,并知道如何复制它。 – BrenBarn

+0

x是一个列表。例如x = [[1,2],[4,5]] –

相关问题