关于python:更改一个列表也会意外地更改另一个列表

Changing one list unexpectedly changes another, too

本问题已经有最佳答案,请猛点这里访问。

我有表格的清单

1
v = [0,0,0,0,0,0,0,0,0]

在密码里的某个地方

1
2
vec=v
vec[5]=5

这改变了vvec

1
2
3
4
>>> print vec
[0, 0, 0, 0, 0, 5, 0, 0, 0]
>>> print v
[0, 0, 0, 0, 0, 5, 0, 0, 0]

为什么v会发生变化?


Why does v change at all?

vec和v都是指针。当编码vec=v时,将v地址分配给vec。因此,改变v中的数据也会"改变"vec。

如果要有两个不同的数组,请使用:

1
vec = list(v)

因为v和vec在内存中指向同一个列表。

如果你不想拥有它,你必须

1
2
from copy import deepcopy
vec = deepcopy(v)

1
vec = v[:]


为了节省内存,除非您特别说明,否则vec将指向同一个数组。

像这样复制数组vec=v[:]

在将数据从函数传递到函数时,指向数组而不是复制数组的功能非常有用。如果你有这个功能

1
2
def foo():
  return someBigArray

你想和大数组做点什么

1
2
3
def bar():
  arr = foo()
  processArray(arr)

您不想浪费时间等待程序将somebigarray中的所有数据复制到arr,因此默认行为是给arr一个指向somebigarray的指针。

有人问了一个类似的问题如何克隆或复制列表?


运行此代码,您将了解变量v为什么会更改。

1
2
3
4
5
6
7
a = [7, 3, 4]
b = a
c = a[:]
b[0] = 10
print 'a: ', a, id(a)
print 'b: ', b, id(b)
print 'c: ', c, id(c)

此代码在我的解释器上打印以下输出:

1
2
3
a:  [10, 3, 4] 140619073542552                                                                                                
b:  [10, 3, 4] 140619073542552                                                                                                
c:  [7, 3, 4] 140619073604136

如您所见,列表A和B指向相同的内存位置。然而,列表C是一个完全不同的内存位置。可以说变量A和B是同一列表的别名。因此,对变量A或B所做的任何更改也将反映在另一个列表中,但不在列表C中。希望这有帮助!:)


你可以使用

1
vec=v[:] #but

"亚历克斯·马泰利(至少在2007年)对这一点的看法是,它是一种奇怪的语法,永远都没有意义。(他认为,下一个更易读)。

1
vec=list(v)

我是说这是埃雷斯的链接…"如何在python中克隆或复制列表?"