3

我是 python 的初学者,我发现关于 mutabilty 的内容非常令人困惑且不直观。给定一个列表:

lst = [[1, 2, 3], [4, 5, 6]]

并尝试在 for 循环中更改列表。

for i in lst:
    i = "test"

我了解这不会更改列表。但:

for i in lst:
    i[1] = "test"

我很惊讶引用子列表会导致以下结果:

[[1, 'test', 3], [4, 'test', 6]]

我试图用可视化器来理解,但我不明白。有人可以用简单的话解释一下吗?谢谢你。

4

4 回答 4

4

在第一种情况下,您只需复制对元素的引用。

i ---> lst[n]

在后一种情况下,您将取消引用引用并更改数据(不在副本中):

i[i] ---> lst[n][i]

因此分配给i[n]将指向实际的可变对象,而不是它的副本。

于 2012-12-15T02:35:27.743 回答
3

赋值(这是=运算符所做的)将值分配给名称。

i是本地命名空间中的变量名。当它在 for 循环中运行时,它指的是一个列表。通过为它分配一个字符串,您会导致名称不再引用列表,而是引用字符串。该列表不受影响——唯一改变的是与名称关联的值。

i[1]是一个名称,用于指定两个列表之一中的特定位置,具体取决于当时i设置的内容。通过为其分配一个字符串,您可以使名称不再引用之前在列表中占据该空间的对象(整数,25取决于列表),而是引用字符串。整数不受影响——唯一改变的是与名称关联的值。

因此,在每种情况下,赋值都在做同样的事情——它使名称指代一个新事物,而不是它所指的旧事物。不同之处在于第二种情况是一个特殊的名称,因为它指的是可变对象的属性。

于 2012-12-15T02:40:24.683 回答
2

for不会复制它产生的每个元素。因此,生成的对象保留了原始对象的所有属性(因为它原始对象),包括可变性。

于 2012-12-15T02:34:30.940 回答
0

因为对于字符串的 for 循环以不同的方式调用,例如 lst 中的 for i:

这意味着如果 lst 是字符串的列表或数组,则 i 直接引用 x[i] 的值,这就是为什么在第一种情况下结果是“test”两次,因为“lst”的长度仅为 2

而在第二种情况下 i[1] 表示 i ------lst[i] i[1]--------`-lst[i][1] 表示第一个值等于 lst[0][ 1]---[1,'test',3] 第二个值等于 lst[1][1]--[4,'test',6]

于 2012-12-15T09:55:39.420 回答