python 中的元组是不是一定不可变?

本文最后更新于:2020年8月16日 下午

先给结论, 元组是不可变的,但是当元组指向可变的变量时,元组就可以改变了。

原理

我们定义这么一个元组,并且输出看看

a = ([1,2,3],[2,3])
print(a)

就会出现这样的结果

([1, 2, 3], [2, 3])

然后我们尝试直接更改元组中的列表

a[1][0]=3
print(a)

就会出现下面这样的输出

([1, 2, 3], [3, 3])

发现没有?原本应该不可变的元组竟然改变了!难道这是什么 bug 么?
让我们看看再仔细看看。

输出元组以及其中的元素的内存地址

print(id(a),id(a[0]),id(a[1]))

得到类似于这样的输出

2252305881536 2252305961792 2252305961664

让我们先记下这些的内存地址,再尝试改变一下其中一个列表的值

a[0][0]=0

再查看一下元组以及其中的元素的内存地址

print(id(a),id(a[0]),id(a[1]))

会发现输出的信息和刚才输出的是一样的。

2252305881536 2252305961792 2252305961664

那么现在就可以得到我们最开始的那个结论了

结论

元组是不可变的,但是当元组指向可变的变量时,元组就可以改变了。

在这里,元组的本身依然时不可变的,因为它指向的内存地址没有发生改变。然而元组所指向的内存地址却不一定是不可变的。因为它可以是列表。在这种情况下,元组就会表现得可变了。

因此我们在使用多维元组时,如果不希望元组有一点的改变的话,就应该把其全部定义为元组,而不应该是元组嵌套列表。

参考

Python 中 tuple+= 赋值的四个问题


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!