2016-11-04 112 views
-1

在python3.5中使用append方法时会出现一些问题。该代码被呈现使用追加方法的Python浅拷贝和深拷贝

# 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,已经附加到basis中的前state也会同时更改。这意味着append自动使用deepcopy这超出了我的理解。事实上,如果我们明确使用basis(state.copy()),这个错误可以被修复。

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

x=3 
b=[] 
b.append(x) 
x=x+2 

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

+2

阅读关于不可变vs可变对象以及传值和传递引用 –

+0

附加不会复制任何内容,这就是为什么您最终在列表中多次显示相同列表的原因。 – spectras

回答

4

正如已在评论中显示的那样,append操作中没有涉及任何副本。因此你必须自己明确地处理这个问题,例如通过用

basis.append(state[:]) 

的切片操作与:替换

basis.append(state) 

创建的state副本。 注意:它不会复制列表元素 - 只要您只保留普通数字,并且列表中的对象应该没有问题。