我以为直到今晚我才知道 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
不也随之改变吗?
你遇到的是引用的概念。 Python 中的所有对象都有一个引用,当您将一个对象分配给两个名称时 a
和 b
, 这会导致 a
和 b
指向同一个对象。
>>> 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]])