更改一个列表也会意外更改另一个列表[重复]
- 2025-01-07 08:44:00
- admin 原创
- 88
问题描述:
我有一份表格清单
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
改变?
解决方案 1:
为什么 v 会发生改变?
vec
和v
均为参考。
编码时,vec = v
您将v
地址分配给vec
。因此,更改中的数据v
也会“改变” vec
。
如果您想要两个不同的数组,请使用:
vec = list(v)
解决方案 2:
因为 v 指向与 vec 在内存中的同一个列表。
如果你不想这样,你必须做出
from copy import deepcopy
vec = deepcopy(v)
或者
vec = v[:]
解决方案 3:
运行此代码你就会明白为什么变量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 上反映出来。希望这能有所帮助!:)
解决方案 4:
Python 将两个列表指向vec = v
内存中的同一位置。
要复制列表,请使用vec = v[:]
这似乎违反直觉。为什么不将复制列表作为默认行为呢?考虑一下这种情况
def foo():
my_list = some_function()
# Do stuff with my_list
您难道不想my_list
包含与在 中创建的完全相同的列表,some_function
而又不想让计算机花费额外的时间来创建副本吗?对于大型列表,复制数据可能需要一些时间。出于这个原因,Python 不会在分配时复制列表。
其他说明:
如果您熟悉使用指针的语言。在内部,在生成的汇编语言中,
vec
和v
只是引用列表在内存中起始地址的指针。其他语言已经能够通过使用写时复制来克服我提到的障碍,该技术允许对象共享内存,直到它们被修改。不幸的是,Python 从未实现这一点。
有关复制列表或进行深层复制的其他方法,请参阅列表在赋值后意外更改。为什么会出现这种情况?我该如何防止这种情况发生?
解决方案 5:
你可以使用
vec=v[:] #but
“Alex Martelli 对此的看法(至少在 2007 年)是,这是一种奇怪的语法,并且永远没有意义使用它。;)(在他看来,下一个更具可读性)。”
vec=list(v)
我的意思是这是 Erez 的链接……“如何在 Python 中克隆或复制列表? ”