Python对象混淆:a = b,修改b和更改!

时间:2011-01-03 20:31:13

标签: python variables reference

我以为我知道Python直到今晚。做这样的事的正确方法是什么?这是我的代码:

a = ["one", "two", "three"]
b = a  # here I want a complete copy that when b is changed, has absolutely no effect on a
b.append["four"]
print a  # a now has "four" in it

基本上我想知道,而不是b = a步骤,我如何正确地复制列表或字典,以便在b更改时a不会改变用它?

3 个答案:

答案 0 :(得分:11)

您所体验的是参考文献的概念。 Python中的所有对象都有一个引用,当您分配一到两个名称ab时,这会导致ab指向相同的< / em> object。

>>> a = range(3)
>>> b = a                     # same object
>>> b.append(3)
>>> a, b                      # same contents
([0, 1, 2, 3], [0, 1, 2, 3])

使用列表,您可以使用b创建另一个a副本的新列表b = a[:]

>>> a = range(3)
>>> b = a[:]                  # make b a new copy of a
>>> b.append(3)
>>> a, b                      # a is left unchanged
([0, 1, 2], [0, 1, 2, 3])

对于任何对象的更通用的解决方案,请使用copy module。浅拷贝将复制存储在您正在复制的对象中的引用,而深拷贝将递归地复制所有对象。

>>> a = [range(2), range(3)]
>>> b = copy.copy(a)          # shallow copy of a, equivalent to a[:]
>>> b[0] = range(4)
>>> a, b                      # setting an element of b leaves a unchanged
([[0, 1], [0, 1, 2]], [[0, 1, 2, 3], [0, 1, 2]])
>>> b[1].append(3)
>>> a, b                      # modifying an element of b modifies the element in a
([[0, 1], [0, 1, 2, 3]], [[0, 1, 2, 3], [0, 1, 2, 3]])

>>> a = [range(2), range(3)]
>>> b = copy.deepcopy(a)      # deep recursive copy of a
>>> b[1].append(3)
>>> a, b                      # modifying anything in b leaves a unchanged
([[0, 1], [0, 1, 2]], [[0, 1], [0, 1, 2, 3]])

答案 1 :(得分:1)

复制对象的正确方法是

 from copy import copy
 a = [1, 2, 3]
 b = copy(a)

非常简单。列表有快捷方式:

 a = [1, 2, 3]
 b = a[:]

如果你想复制列表中的对象,还有deepcopy()。

答案 2 :(得分:1)

以下是制作列表a副本的3种方法:

使用切片表示法:

copy_of_a = a[:]

使用列表构造函数:

copy_of_a = list(a)

使用复制模块:

from copy import copy
copy_of_a = copy(a)

这些都是浅色副本,足以满足您的提问。要了解浅拷贝和深拷贝之间的区别,请阅读documentation of the copy module