Python append方法中的浅拷贝和深拷贝
Python shallow copy and deep copy in using append method
在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
后,原来追加到basis
中的state
也同步变了。这意味着 append
自动使用 deepcopy
这超出了我的理解。事实上,如果我们明确地使用 basis(state.copy())
就可以修复这个错误。
另一方面,下面的简单代码显示使用append
没有错误
x=3
b=[]
b.append(x)
x=x+2
x
改为x=5
后,b
不变b=[3]
。真让我费解,似乎与前面的例子矛盾。
正如评论中已经揭示的那样,append
操作中不涉及任何副本。
所以你必须自己明确地处理这个问题,例如通过替换
basis.append(state)
和
basis.append(state[:])
:
的切片操作创建了 state
的副本。
注意:它不会复制列表元素 - 只要您只保留纯数字而不是列表中的对象就可以了。
在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
后,原来追加到basis
中的state
也同步变了。这意味着 append
自动使用 deepcopy
这超出了我的理解。事实上,如果我们明确地使用 basis(state.copy())
就可以修复这个错误。
另一方面,下面的简单代码显示使用append
x=3
b=[]
b.append(x)
x=x+2
x
改为x=5
后,b
不变b=[3]
。真让我费解,似乎与前面的例子矛盾。
正如评论中已经揭示的那样,append
操作中不涉及任何副本。
所以你必须自己明确地处理这个问题,例如通过替换
basis.append(state)
和
basis.append(state[:])
:
的切片操作创建了 state
的副本。
注意:它不会复制列表元素 - 只要您只保留纯数字而不是列表中的对象就可以了。