可变对象与不可变对象具体列出

Mutable vs. Immutable object specifically lists

我对列表的可变性有疑问。我目前正在阅读 YouTuber/Programmer senddex 的教程,其中一个问题是对象和列表的可变性与不变性。

示例 1:

x = [1]
print(id(x))

def test():
    x = [2]
test()
print(x)
print(id(x))

在这个例子中 x 仍然是 [1]。

示例 2:

x = [1]
print(x)
print(id(x))
def test():
    x [0]= 2
test()
print(x)
print(id(x))

在此示例中,x 更改为 [2]。

所以我的问题是,列表是否仅在通过特定函数内的索引值更改列表时才可变?

感谢您的帮助!

“可变”意味着您可以更改对象中的特定元素。对于不可变对象,如果您想要为特定元素赋予不同的值,则必须重新分配整个对象。列表始终具有更改特定元素的能力。在你的第二个例子中,列表仍然是可变的,但你没有改变它。你正在重新分配它。

在Python中,调用函数时,默认行为是所有变量names的范围都在函数内,但函数有完全访问 对象 。当您编写 x[0] = 2 时,您正在访问实际对象,并更改该对象的第一个元素。当你写 x = [2] 时,你不再处理同一个对象,你只处理 name "x",以及 name 仅在函数内。但是,如果您在函数中编写了 global x,那么这将告诉 Python 您希望名称“x”具有全局范围,并且它会将名称“x”重新分配给新对象[2] 整个程序。然后您会在主程序中看到 x[0]id(x) 的不同值。

这是一件很难解释的事情,因为问题在于对象的名称与该名称所指的对象之间的区别,不使用它们的名称就很难谈论对象。我不知道这是否使事情变得更清楚或更令人困惑,但假设我们将第一个列表称为 object1,将第二个列表称为 object2(也就是说,如果您采用第一个对象的 id,我们会假设您得到1,如果你取第二个的id,你得到2)。当您调用 test 时,您传递了名称为“x”的对象 1。如果你有行 x=[2],你正在创建对象 2,将值 2 放入其中,并告诉 Python 在函数 test 中,名称 x 指向对象 2。另一方面,如果您有行 x[0]=2,您仍在处理 object1,并且您正在将其第一个元素的值更改为 2.