【发布时间】:2020-10-24 16:31:56
【问题描述】:
在被调用时作为可变对象的列表正在传递引用(如果我的理解是正确的,它本质上是传递 id)。在下面的代码中,我分配了一个列表 A 的列表。我将它称为修改 M 的名为 modify(M) 的函数。正如预期的那样,A 和 M 具有相同的 id,并且修改 M 也会修改 A。到目前为止一切都很好。
但是,我随后将 A 重新分配为原始值(如预期的那样更改其 id)。然后我调用 modify(A*1),即将复制的 A 作为参数传递。正如预期的那样,现在 A 和 M 具有不同的 id,而 M 是 A 返回 False。 但是,改变 M 仍然会改变 A,这与我的预期相反。这是为什么呢?
注意:调用 modify(A[:]) 也会产生同样的意外(我)行为。
我知道答案与我有一个列表有关。 (当我仅使用一级列表尝试此操作时,我得到了预期的行为。)
由于我是 Python 编码的相对初学者,我非常感谢初学者可能理解的答案。
代码如下:
def modify(M):
print(M is A)
print('id of M', id(M))
print('id of A', id(A))
print('Original list of lists before change in M =', A)
M[0][0]=M[1][1] #some modification of M
print('Original list of lists after change in M =', A)
print(M is A)
print('id of M', id(M))
print('id of A', id(A))
A=[[1,2],[3,42]]
modify(A) #Argument is the list
print("\n","*****What happens below is driving me crazy!*****","\n")
A=[[1,2],[3,42]]
modify(A*1) #Argument is replicated list of lists
#modify(A[:]) has the same behavior
编辑:我刚刚发现并没有为我回答这个问题,但可能为比我更擅长 Python 的人回答了这个问题。
它要求您导入副本。
- 将
modify(A*1)替换为modify(copy.copy(A))。观察到完全相同的奇怪行为。换句话说,id 变了,而 M 变了,A 也变了。 - 将
modify(A*1)替换为modify(deepcopy.copy(A))。我所期望的会发生。换句话说,id 变了,M 变了,A 也不会变。
【问题讨论】:
-
如果你使用不可变的数据结构作为参数(比如元组)也会发生同样的事情
-
好问题。当然,如果将 A 分配为元组的元组,则代码会崩溃。但是如果将 A 分配为列表 A=([1,2],[3,42]) 的元组,则 A 在 M 更改时再次更改,但现在 A 和 M 具有相同的 id
-
是的,我的意思是一个元组的元组
-
对于一个元组的元组,您尝试修改一个元组并且您得到 TypeError: File "L:__Transfer\test0008.py", line 13, in modify M[0][0]= M[1][1] #M TypeError的一些修改:'tuple'对象不支持项赋值
-
是的,你必须复制对象
标签: python list function arguments