我是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]]
我尝试用可视化工具理解,但我没理解。有人请用简单的话解释一下吗?谢谢。
答案 0 :(得分:4)
在第一种情况下,您只需要复制对该元素的引用。
i ---> lst[n]
在后一种情况下,您解除引用引用和更改数据(不在副本中):
i[i] ---> lst[n][i]
因此,分配给i[n]
将指向实际的可变对象,而不是它的副本。
答案 1 :(得分:3)
分配(=
运算符所做的)为名称赋值。
i
是本地名称空间中的变量名。当它在for循环中运行时,它引用一个列表。通过为其指定字符串,可以使名称不再引用列表,而是引用字符串。该列表不受影响 - 唯一改变的是与名称相关联的值。
i[1]
是一个名称,用于指定两个列表中某个列表中的特定位置,具体取决于当时设置的i
。通过为其指定一个字符串,可以使名称不再引用先前占据列表中该空间的对象(取决于列表的整数,2
或5
),而是引用字符串。整数不受影响 - 唯一改变的是与名称关联的值。
因此,在每种情况下,赋值都在做同样的事情 - 它使一个名称引用一个新的东西,而不是它引用的旧东西。区别在于第二种情况是一个特殊名称,因为它引用了一个可变对象的属性。
答案 2 :(得分:2)
for
不会复制它产生的每个元素。因此,产生的对象保留了原始的所有属性(因为它 原始属性),包括可变性。
答案 3 :(得分:0)
因为在字符串的情况下for循环以不同的方式调用 喜欢 我在lst:
这意味着如果lst是列表或字符串数组,那么我直接引用x [i]的值,这就是为什么在第一种情况下结果是“test”两次因为“lst”的长度只是2
而在第二种情况下,我[1]的意思是 我------ lst [i] 我[1] --------` -lst [i] [1]的意思是 第一个值等于lst [0] [1] --- [1,'test',3] 第二个值等于lst [1] [1] - [4,'test',6]