Python 更改一个列表也会意外地更改另一个列表

Python 更改一个列表也会意外地更改另一个列表,python,python-2.7,Python,Python 2.7,我有一张表格的清单 v = [0,0,0,0,0,0,0,0,0] 在代码的某个地方,我知道 vec=v vec[5]=5 这会同时改变v和vec: >>> print vec [0, 0, 0, 0, 0, 5, 0, 0, 0] >>> print v [0, 0, 0, 0, 0, 5, 0, 0, 0] 为什么v会发生变化?Python将vec=v中的两个列表指向相同的内存点 要复制列表,请使用vec=v[:] 这一切似乎都违反直觉。为什么不将

我有一张表格的清单

v = [0,0,0,0,0,0,0,0,0]
在代码的某个地方,我知道

vec=v
vec[5]=5
这会同时改变
v
vec

>>> print vec
[0, 0, 0, 0, 0, 5, 0, 0, 0]
>>> print v
[0, 0, 0, 0, 0, 5, 0, 0, 0]

为什么
v
会发生变化?

Python将
vec=v
中的两个列表指向相同的内存点

要复制列表,请使用
vec=v[:]


这一切似乎都违反直觉。为什么不将复制列表作为默认行为?考虑形势

def foo():
my_list=某些_函数()
#用我的清单做事
您是否希望
my_list
包含与
some_function
中创建的列表完全相同的列表,而不必花费时间创建它的副本。对于大型列表,复制数据可能需要一些时间。由于这个原因,Python不会在赋值时复制列表



其他注释:

  • 如果您熟悉使用指针的语言。在内部,在生成的汇编语言中,
    vec
    v
    只是引用列表开始的内存地址的指针

  • 其他语言已经能够克服我提到的障碍,通过使用它,对象可以共享内存,直到它们被修改。不幸的是,Python从未实现过这一点

  • 有关复制列表或进行深度复制的其他方法,请参阅


因为v指向的列表与vec在内存中的列表相同

如果你不想拥有它,你必须做出选择

from copy import deepcopy
vec = deepcopy(v)

为什么v会改变

vec
v
都是参考资料

编码
vec=v
时,将
v
地址分配给
vec
。 因此,更改
v
中的数据也将“更改”
vec

如果要使用两个不同的阵列,请使用:

vec = list(v)
你可以用

vec=v[:] #but
“Alex Martelli对此的看法(至少在2007年)是,这是一种奇怪的语法,使用它是没有意义的。”(在他看来,下一个更具可读性)


我是说那是Erez的链接。。。“

运行此代码,您将了解变量v更改的原因

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)
此代码在我的解释器上打印以下输出:

a:  [10, 3, 4] 140619073542552                                                                                                
b:  [10, 3, 4] 140619073542552                                                                                                
c:  [7, 3, 4] 140619073604136
如您所见,列表a和b指向相同的内存位置。然而,列表c是一个完全不同的内存位置。可以说变量a和b是同一列表的别名。因此,对变量a或b所做的任何更改也将反映在其他列表中,但不会反映在列表c中
希望这有帮助!:)

值得注意的是,这种行为不仅限于列表,它还可以通过dict对象观察到,如果元组是可变的,它也会出现在元组上。@SimeonVisser我不可能事先知道。如果我想到用关键字指针搜索,我就不会发布这个问题了。你不需要一个肤浅答案的深度副本
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)
a:  [10, 3, 4] 140619073542552                                                                                                
b:  [10, 3, 4] 140619073542552                                                                                                
c:  [7, 3, 4] 140619073604136