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从未实现过这一点
- 有关复制列表或进行深度复制的其他方法,请参阅
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