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

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

原理

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

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

就会出现这样的结果

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

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

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

就会出现下面这样的输出

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

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

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

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

得到类似于这样的输出

1
2252305881536 2252305961792 2252305961664

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

1
a[0][0]=0

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

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

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

1
2252305881536 2252305961792 2252305961664

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

结论

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

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

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

参考

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


python中的元组是不是一定不可变?
https://www.yikakia.com/python中的元组是不是一定不可变?/
作者
Yika
发布于
2020年4月3日
许可协议