使用append方法的Python浅表复制和深表复制

Ach*_*sJJ 1 python copy deep-copy python-3.x

在python3.5中使用append方法时会出现一些问题。代码显示

# generate boson basis in lexicographic order
def boson_basis(L,N):
basis=[]
state=[0 for i in range(1,L+1)]
pos=0
# initialize the state to |N,0,...,0>
state[0]=N
basis.append(state)
# find the first non-zero position in reverse order
while state[L-1]<N:
    for i in range(-2,-L-1,-1):
        if state[i]>0:
            pos=L+i
            break
    sum=0
    for i in range(0,pos):
        sum=sum+state[i]
    state[pos]=state[pos]-1
    state[pos+1]=N-sum-state[pos]
    basis.append(state)
return basis        

result=boson_basis(3,3)
Run Code Online (Sandbox Code Playgroud)

预期结果应该是[[3,0,0],[2,1,0],...,[0,0,3]],但是此代码会产生错误的结果,并且所有元素都与最后一个元素相同,即[[0,0,3],...,[0,0,3]]。我使用pdb对其进行调试,我发现一旦state修改了,state附加到其中的前者basis也会同时更改。它意味着自动append使用deepcopy,这超出了我的理解。实际上,如果我们basis(state.copy())显式使用,则可以修复此错误。

另一方面,以下简单代码显示使用中没有错误 append

x=3
b=[]
b.append(x)
x=x+2
Run Code Online (Sandbox Code Playgroud)

x改为x=5b保持不变b=[3]。这确实使我感到困惑,并且似乎与前面的示例矛盾。

seb*_*ian 8

正如评论中已经揭示的那样,append操作中没有任何副本。因此,您必须自己明确地进行维护,例如,通过更换

basis.append(state)
Run Code Online (Sandbox Code Playgroud)

basis.append(state[:])
Run Code Online (Sandbox Code Playgroud)

的切片操作可:创建的副本state。注意:它不会复制list元素-只要您仅保留纯数字,而不保留列表中的对象就可以了。