使用append方法的Python浅拷贝和深拷贝

时间:2016-11-04 14:47:34

标签: python python-3.x copy deep-copy

在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)

预期结果应为[[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

x更改为x=5后,b保持不变b=[3]。它真的让我感到困惑,似乎与前一个例子相矛盾。

1 个答案:

答案 0 :(得分:5)

正如评论中所揭示的那样,append操作中没有任何副本。 因此,您必须自己明确地处理此问题,例如:通过替换

basis.append(state)

basis.append(state[:])

:的切片操作会创建state的副本。 记住:它不会复制列表元素 - 只要你只保留普通数字而不是列表中的对象应该没问题。