创建彼此独立的Python变量

时间:2013-05-03 15:34:47

标签: python list

如果我有这个Python代码:

foo = [3, 5, 9]
bar = foo
bar.append(9)
print(foo)

返回

[3, 5, 9, 9]

这肯定意味着当我将9添加到bar时,它也会影响foo。如何使变量bar等于foo,但是当我修改bar时,它不会影响foo

4 个答案:

答案 0 :(得分:5)

您正在更改可变值,因此您需要制作一个明确的副本:

bar = list(foo)

bar = foo[:]

在Python中分配名称时,您只需将引用存储到该值中。如果不创建列表副本,foobar都会引用相同的列表。

对于非可变值,这不是问题;你将一个字符串的引用替换为一个字符串,而不是指向一个不同的值。

但是列表(以及dictset以及大多数类的实例)都是可变的。您没有更改foo,您更改了foo引用。你做了foo.append(9),Python认为:

  • 找到foo引用的值。
  • 在该值上找到属性.append。这将返回列表实例上的方法。
  • 调用方法,传入值9。这改变了清单。

Python名称本身只不过是标签,指向实际值。您可以将值视为气球,将名称视为小纸标签,分配是将标签绑定到气球的行为。 bar = foo创建了第二个纸质标签,该标签与完全相同的气球相关联。

请参阅此older answer of mine我将气球比喻推到一起。

答案 1 :(得分:2)

你制作副本:

bar = foo[:]  #copy of foo
bar.append(9)

这与python如何处理赋值有关。分配说“将对象放在右侧并将其存储在本地命名空间左侧的名称下”。所以,在你的情况下,你有foo和bar引用同一个对象,这就是为什么追加到另一个也会影响另一个对象。

当使用通常操作对象的运算符(例如+=)时,对于不可变对象,事情会变得更有趣。例如,请参阅my answer here以及更多解释。

答案 2 :(得分:2)

在删除对原稿的所有引用(因此无法编辑原件)时创建原件的副本时,使用深层复制。

http://docs.python.org/2/library/copy.html

import copy
bar = copy.deepcopy(foo)

答案 3 :(得分:2)

使用deepcopy

>>> from copy import deepcopy
>>> foo = [3, 5, 9]
>>> bar = deepcopy(foo)
>>> bar.append(9)
>>> print(foo)
[3, 5, 9]
>>> print bar
[3, 5, 9, 9]