提问人:sodiumnitrate 提问时间:4/22/2015 最后编辑:wjandreasodiumnitrate 更新时间:9/22/2023 访问量:42641
更改一个列表也会意外更改另一个列表 [重复]
Changing one list unexpectedly changes another, too [duplicate]
问:
我有一个表格列表
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 = some_function()
# Do stuff with my_list
难道您不想包含与创建的完全相同的列表,并且不让计算机花费额外的时间创建副本吗?对于大型列表,复制数据可能需要一些时间。由于这个原因,Python 不会在赋值时复制列表。my_list
some_function
其他注意事项:
如果您熟悉使用指针的语言。在内部,在生成的汇编语言中,只是引用内存中列表开始的地址的指针。
vec
v
其他语言已经能够通过使用写入时复制来克服我提到的障碍,它允许对象共享内存,直到它们被修改。不幸的是,Python 从未实现过这一点。
有关复制列表或执行深层复制的其他方法,请参阅分配后列表意外更改。为什么会这样,我该如何预防?
因为 v 指向的列表与 vec 在内存中的列表相同。
如果你不想拥有它,你必须做一个
from copy import deepcopy
vec = deepcopy(v)
或
vec = v[:]
评论
为什么 v 会改变?
vec
和都是参考。v
编码时,将地址分配给 。
因此,更改数据也会“更改”。vec = v
v
vec
v
vec
如果要使用两个不同的数组,请使用:
vec = list(v)
你可以使用
vec=v[:] #but
“Alex Martelli(至少在2007年)对此的看法是,这是一种奇怪的语法,使用它是没有意义的。 ;)(在他看来,下一个更具可读性)。
vec=list(v)
我的意思是这是埃雷兹的链接......“如何在Python中克隆或复制列表?"
运行这段代码,你就会明白为什么变量 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 中 希望这有帮助!:)
评论