复制后的Python列表变异

时间:2017-11-05 00:09:10

标签: python python-3.x immutability

[10, 1, 2]
[0, 1, 2]

在最顶层的代码片段中,我制作了一份列表副本并对其进行了修改。然后我将原件设置为副本然后它可以工作。 令我困惑的是为什么在函数之外执行此过程有效,但如果我在函数内部(第二段代码)执行此操作,它会失败?

作为参考,代码返回:

input_list[0] = 10
编辑:我知道调用<div id="ComponentTemplateHTML" style="width:1000px;height:600px;border:1px solid grey"></div> 有效。我只是想知道是什么让我与我在内存中显示的内容有所不同?

3 个答案:

答案 0 :(得分:4)

mutation中,input_list开始指向与sample_list相同的对象,但稍后您将其指向list_copysample_list未被修改。它仍然指向原始对象。

在功能之外执行此操作时,您可以在打印之前将sample_list更改为指向新对象。

答案 1 :(得分:1)

我认为使用内置函数id来显示对象ID会有所帮助。如果两个变量名的ID给出相同的结果,那么它们引用同一个对象;否则对象就不同了。

>>> def mutation(input_list):
...     print(id(input_list))
...     list_copy = input_list[:]
...     print(id(list_copy))
...     input_list = list_copy
...     print(id(input_list))
...     
>>> a = list(range(10))
>>> print(id(a))
140737233394376
>>> mutation(a)
140737233394376
140737233289160
140737233289160

在上面,我们看到在input_list = list_copy之后,名称input_list在内存中指的是与list_copy完全相同的对象,这意味着它不再引用给定的列表函数参数。这就是为什么你期望的突变不起作用的原因 - 你正在修改一个完全不同的对象。

答案 2 :(得分:0)

这是因为你为input_list设置了mutation函数的局部变量的新值。

最简单的解决方案是更改作为参数传递的列表的第一个元素的值:

def mutation(input_list):
    input_list[0] = 10

否则,您可以编写更改名为sample_list

的全局变量值的函数
def mutation():
    global sample_list
    list_copy = sample_list[:]
    list_copy[0] = 10
    sample_list = list_copy