Python复制后列出变异
Python list mutation after copying
def mutation(input_list):
list_copy = input_list[:]
list_copy[0] = 10
input_list = list_copy
# Correctly mutates
sample_list = [0,1,2]
sample_copy = sample_list[:]
sample_copy[0] = 10
sample_list = sample_copy
print(sample_list)
# Incorrectly mutates
sample_list = [0,1,2]
mutation(sample_list)
print(sample_list)
在上面的代码片段中,我复制了一个列表并对其进行了修改。然后我将原件设置为副本,然后它就可以工作了。
让我感到困惑的是,为什么在函数外部执行此过程有效,但如果我在函数内部执行此过程(第二段代码),它会失败?
供参考,代码returns:
[10, 1, 2]
[0, 1, 2]
编辑:我知道调用 input_list[0] = 10
有效。我只想知道这与我首先在内存中显示的有什么不同?
那是因为你为 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
在 mutation
中,input_list
开始指向与 sample_list
相同的对象,但后来您将其指向 list_copy
。
sample_list
未修改。它仍然指向原始对象。
当您在函数之外执行此操作时,您会更改 sample_list
以在打印之前指向新对象。
我认为使用内置函数 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
在内存中指代的是同一个对象,也就是说不再指代列表作为函数参数给出。这就是您期望的突变不起作用的原因 - 您正在修改一个完全不同的对象。
def mutation(input_list):
list_copy = input_list[:]
list_copy[0] = 10
input_list = list_copy
# Correctly mutates
sample_list = [0,1,2]
sample_copy = sample_list[:]
sample_copy[0] = 10
sample_list = sample_copy
print(sample_list)
# Incorrectly mutates
sample_list = [0,1,2]
mutation(sample_list)
print(sample_list)
在上面的代码片段中,我复制了一个列表并对其进行了修改。然后我将原件设置为副本,然后它就可以工作了。 让我感到困惑的是,为什么在函数外部执行此过程有效,但如果我在函数内部执行此过程(第二段代码),它会失败?
供参考,代码returns:
[10, 1, 2]
[0, 1, 2]
编辑:我知道调用 input_list[0] = 10
有效。我只想知道这与我首先在内存中显示的有什么不同?
那是因为你为 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
在 mutation
中,input_list
开始指向与 sample_list
相同的对象,但后来您将其指向 list_copy
。
sample_list
未修改。它仍然指向原始对象。
当您在函数之外执行此操作时,您会更改 sample_list
以在打印之前指向新对象。
我认为使用内置函数 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
在内存中指代的是同一个对象,也就是说不再指代列表作为函数参数给出。这就是您期望的突变不起作用的原因 - 您正在修改一个完全不同的对象。