Why are lists linked in Python in a persistent way?
设置了一个变量。另一个变量设置为第一个。第一个更改值。第二个没有。这是自时代开始编程的本质。
1 2 3 4 5 6 7 | >>> a = 1 >>> b = a >>> b = b - 1 >>> b 0 >>> a 1 |
然后我将其扩展到python列表。声明并附加一个列表。另一个列表声明为等于第一个列表。第二个列表中的值更改。奇怪的是,第一个列表中的值虽然没有直接作用,但也会发生变化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> alist = list() >>> blist = list() >>> alist.append(1) >>> alist.append(2) >>> alist [1, 2] >>> blist [] >>> blist = alist >>> alist.remove(1) >>> alist [2] >>> blist [2] >>> |
为什么会这样?
我该如何防止这种情况发生——我希望
型
python变量实际上不是变量,而是对对象的引用(类似于c中的指针)。在http://foobarnbaz.com/2012/07/08/understanding-python-variables中有一个很好的解释,对初学者来说。/
让自己相信这一点的一种方法是尝试:
1 2 3 4 5 6 | a=[1,2,3] b=a id(a) 68617320 id(b) 68617320 |
。
id返回给定对象的内存地址。因为这两个列表都是相同的,这意味着改变一个列表会影响另一个列表,因为它们实际上是相同的。
型
python中的变量绑定的工作方式是:将对象赋给变量。
1 2 | a = 4 b = a |
两者都指向
1 | b = 9 |
。
现在,
列表也会发生同样的情况:
1 2 3 | a = [] b = a b = [9] |
。
现在,
到目前为止,一切都很清楚,对于可变和不变的对象,您有相同的行为。
现在出现了你的误解:这是关于修改物体。
1 2 3 4 5 6 7 8 9 10 | a = [] b = a # the same list c = [] # another empty one a.append(3) print a, b, c # a as well as b = [3], c = [] as it is a different one d = a[:] # copy it completely b.append(9) # now a = b = [3, 9], c = [], d = [3], a copy of the old a resp. b |
型
发生的情况是,当您执行以下操作时,会创建对同一列表的另一个引用:
1 | blist = alist |
因此,
如果要复制整个列表,而不仅仅是创建引用,可以执行以下操作:
1 | blist = alist[:] |
号
实际上,您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 | >>> alist = [1,2] >>> blist = [] >>> id(alist) 411260888 >>> id(blist) 413871960 >>> blist = alist >>> id(blist) 411260888 >>> blist = alist[:] >>> id(blist) 407838672 |
这是来自python文档的相关引用:
Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.
号
型
基于此帖:
Python passes references-to-objects by value (like Java), and
everything in Python is an object. This sounds simple, but then you
will notice that some data types seem to exhibit pass-by-value
characteristics, while others seem to act like pass-by-reference...
what's the deal?It is important to understand mutable and immutable objects. Some
objects, like strings, tuples, and numbers, are immutable. Altering
them inside a function/method will create a new instance and the
original instance outside the function/method is not changed. Other
objects, like lists and dictionaries are mutable, which means you can
change the object in-place. Therefore, altering an object inside a
function/method will also change the original object outside.
号
所以在您的示例中,您要使变量
型
简短的回答2你的问题"这是为什么?":因为在python中,整数是不可变的,而列表是可变的。
您在python文档中寻找官方参考。看看这一部分:http://docs.python.org/2/reference/simple诳stmts.html诳赋值语句
引自后者:
Assignment statements are used to (re)bind names to values and to
modify attributes or items of mutable objects
号
我真的很喜欢这句话,以前从没见过。它精确地回答了你的问题。
最近关于这个主题的一篇好文章是http://nedbatchelder.com/text/names.html,其中一条评论中已经提到过。