Python 为什么当我附加到元组中的列表时,元组的内容会改变,而当我更新变量时,元组的内容不会改变?

Python 为什么当我附加到元组中的列表时,元组的内容会改变,而当我更新变量时,元组的内容不会改变?,python,list,append,tuples,variable-assignment,Python,List,Append,Tuples,Variable Assignment,为什么以及如何在构造后通过追加修改此元组 myVar = ["jhhj", "hgc"] myTuple = ([1,2,3], [4,5,6], myVar) myVar.append('lololol') print myTuple 为什么要打印出([1,2,3],[4,5,6],“lol”)而不是([1,2,3],[4,5,6],“LOLOLOL”)?元组是不可变的,所以如果要修改它的一个成员,就需要构造一个新的元组…python中的所有东西都是对象 所以当你完成最初的任务时 myVar

为什么以及如何在构造后通过追加修改此元组

myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
myVar.append('lololol')
print myTuple

为什么要打印出
([1,2,3],[4,5,6],“lol”)
而不是
([1,2,3],[4,5,6],“LOLOLOL”)

元组是不可变的,所以如果要修改它的一个成员,就需要构造一个新的元组…

python中的所有东西都是对象

所以当你完成最初的任务时

myVar=“lol”

您正在向myVar提供对对象“lol”的引用

然后创建一个元组。第三个槽中的这个元组引用了“lol”


然后创建一个新对象“lolol”,并给myVar一个对它的引用。元组保留其对“lol”的原始引用。

元组是不可变的,但您可以将它们连接在一起,如:

myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
myVar = "lolol"
print myTuple

好吧,让我试着用一些图片来解释

在Python中,一切都是对象。这些对象由变量引用。某些类型的对象,例如列表和元组,只存储对其他对象的引用

也就是说,当你执行

var a = (1, 2)
var b = a + (3, 4)
myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
您或多或少会遇到这种情况:

每个对象由一个方框/矩形表示。我们有两个字符串对象,
“jhj”
“hgc”
。此外,我们还有一个列表对象,由变量
myVar
指向;此列表对象指向两个字符串对象。此外,我们还有一个tuple对象,由
myTuple
引用;这个tuple对象指向另外两个列表和
myVar
引用的列表

当你执行

var a = (1, 2)
var b = a + (3, 4)
myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
发生了什么事?好的,列表对象(由
myVar
附带指出)开始引用另一个值,字符串对象
“lolool”

请注意,
myVar
仍然引用列表对象。发生的情况是列表对象发生了更改。您可以从
myVar
或元组查看此列表对象,您将看到具有相同更改的相同对象

奥托,当你执行

myVar.append('lololol')
你会得到这样的结果:

现在
myVar
指向字符串对象
“lol”
,元组在第三个位置引用它。现在,如果你执行

var a = (1, 2)
var b = a + (3, 4)
myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
您只是使
myVar
指向另一个对象。元组对象仍然像以前一样指向
“lol”

因此,如果您将一个新值赋予一个变量,它只会更改该变量所指向的值。变量引用的前一个值仍然存在*并且指向它的任何其他变量或对象将保持指向它。只有属性变量会改变

PS:还有。你可能会发现这个答案很有帮助


*除非它是由垃圾收集器收集的,但这是另一个很长的历史。

在这两种情况下,当您创建元组时,您正在复制对当时的对象
myvar
的引用

在第一种情况下,
myvar
是一个可变对象。可以在元组中存储对对象的引用后更改该对象


在第二种情况下,
myvar
是一个不可变的字符串。您不能更改对象,但可以更改
myvar
本身所指的内容。但这并不会改变元组中包含的对象。

在其他答案中有一些要点,我将不再重复,以解释名称和对象之间的差异。我认为所缺少的只是当一些Python代码在名称上运行时以及在对象上运行时的拼写

但是,您需要了解的一个关键问题是,唯一直接影响名称的是赋值语句[1]。赋值语句重新绑定名称以指向不同的对象。出现在任何其他上下文中的名称只是执行该行代码时名称绑定到的任何对象的简单表示

让我们看看您的示例中的这一行:

myVar = "lolol"
myTuple
出现在赋值语句的左侧,因此名称
myTuple
是受影响的名称<另一方面,code>myVar位于表达式内部,因此它是绑定到元组第三个元素的对象
myVar
,而不是名称
myVar

因此,名称
myVar
后面发生的任何事情都不会对元组产生任何影响。但只要元组的第三个元素和
myVar
引用同一个对象,更改该对象(通过
myVar
或元组)显然会影响通过任一引用查看对象时得到的结果


[1] 对于高级学习,
def
class
语句也是“赋值语句”(它们创建函数或类,然后将其赋值给名称)

此外,诸如
+=
*=
等运算符有时是赋值语句,有时不是赋值语句,具体取决于LHS上名称当前引用的对象类型:

myTuple = ([1,2,3], [4,5,6], myVar)

那么,为什么在程序的后面附加一个列表会修改原始元组呢?您是在修改元组中的list对象,而不是在修改元组。您正在修改元组的列表成员。一个稍微不准确但很有用的方法是元组
([1,2],[3,4])
实际上是
(address_to_list1,address_to_list2)
您不能更改地址,但列表是独立的、可变的对象。为什么在程序中添加list myVar会修改原始元组?