【问题标题】:Python shallow copy and deep copy in using append methodPython浅拷贝和深拷贝中使用append方法
【发布时间】:2017-03-18 10:58:53
【问题描述】:

在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 不会复制任何内容,这就是为什么您最终会在列表中多次出现相同的列表。

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


【解决方案1】:

正如 cmets 已经揭示的那样,append 操作中不涉及任何副本。 所以你必须自己明确地处理这个问题,例如通过替换

basis.append(state)

basis.append(state[:])

使用: 的切片操作会创建state 的副本。 注意:它不会复制列表元素——只要你只保留普通数字而不是列表中的对象就可以了。

【讨论】:

    猜你喜欢
    • 2015-01-13
    • 2012-04-12
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    相关资源
    最近更新 更多