修改嵌套列表的副本会修改原始列表[重复]

Posted

技术标签:

【中文标题】修改嵌套列表的副本会修改原始列表[重复]【英文标题】:Modifying copy of nested list modifies the original list [duplicate] 【发布时间】:2019-03-27 17:14:33 【问题描述】:
z=[2,3,4]
a=[[],[1,1,1],[1,1,1,1]]
learning_rate=0.3

def _update_iteration(z,a,learning_rate):
    a2=a
    print(a)
    print(a2)
    for q in range(1):
        for j in range(z[q+1]):
            a2[q+1][j]=a[q+1][j]-learning_rate
    print(a)
    print(a2)
    print('test')

_update_iteration(z,a,learning_rate)
_update_iteration(z,a,learning_rate)

如果您运行代码,输出将表明变量 a 已更改,即使我从未说过类似 a=... 的内容。

我能做什么?

【问题讨论】:

【参考方案1】:

在 python 中,MutableImmutable 类型之间存在区别。不可变类型不能更改其内部状态(例如,整数没有内部状态,而是纯值)。然而,列表和其他对象可以改变它们的状态,因此是可变的。

将不可变类型的变量分配给新变量时,python 内部会节省内存并让两个变量指向内存中的相同位置/地址(因为 value/data-behind-the-variable 是不可变的,没有理由在内存中有另一个副本)

然而,对于可变类型而言,仅指向内存中相同位置的简单技巧意味着您还可以更改该数据的内部状态并查看所有引用变量的更改。

为避免这种情况,您必须复制该内部数据,然后引用该副本。

要实现这一点,您必须更改行:

a2 = a

from copy import deepcopy

a2 = deepcopy(a)

【讨论】:

感谢您的回答!虽然我不明白其中的区别。我一直认为等号分配了一个新变量.. @Martin 我改变了我的答案,希望这能帮助你理解 ;) 再次感谢您的新答案!我以某种方式理解得更好,虽然我不明白为什么整数总是不可变的......而且,当我将 a2=a 更改为 a2=a.copy() 它不起作用(仍然是同样的问题)。并且 deepcopy() 导致错误。难道我做错了什么?你能发布更正的代码吗?谢谢=) @Martin 你必须导入 deepcopy 函数 (我忘了这个)。然而,似乎这个问题之前已经回答过,所以这个答案可能更容易理解。

以上是关于修改嵌套列表的副本会修改原始列表[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在python中复制列表[重复]

在python中复制列表[重复]

通过旧列表修改列表副本的错误

修改JavaScript对象的副本会导致原始对象发生更改

javascript 修改JavaScript对象的副本会导致原始对象发生更改

《问题总结》分类列表拖拽排序后,接着修改下拉选项值,分类列表排序顺序重新回到原始状态