在Python中,元组是不可变对象但允许包含列表的变异?

时间:2016-02-05 13:23:21

标签: python

在Python中:

>>> tup = (1,"a",[1,2,3])
>>> tup
(1, 'a', [1, 2, 3])
>>> tup[2][1] = "a"
>>> tup
(1, 'a', [1, 'a', 3])

从上面我可以修改列表内容,它是元组的一部分。由于元组是不可变的,这怎么可能? 我是否以错误的方式理解了不可变部分?

3 个答案:

答案 0 :(得分:6)

你确实理解了不可变部分的错误方式。元组确实是不可变的,因为你不能改变它的列表:

In [3]: tup[2] = []
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-02255d491606> in <module>()
----> 1 tup[2] = []

TypeError: 'tuple' object does not support item assignment

列表中的引用在该元组中是不可变的。但是,列表本身是可变的,因此可以修改,如您所知。

换句话说,你的元组是不可变的,包含三个元素:

  • 整数1
  • string&#34; a&#34;
  • 参考到列表。

你可以把它想象成列表的地址,如果你知道C.如果你对记忆一无所知,你可以把它视为&#34;元组知道哪里找到清单&#34;。但它本身并不包含列表。

答案 1 :(得分:2)

元组容器是不可变的,但其中的元素可能是也可能不是不可变的。

您的示例中的元组确实是不可变的,但它包含对可变列表的引用

  

所以最后我能修改元组内容吗?

不,你不能让元组指向不同的列表,但你可以改变列表中的内容。

当你执行tup[2][1]="a"时,你没有改变元组,你改变了列表。元组仍然具有与列表相同的引用

要查看引用未更改的代码段:

我们可以使用id(),它返回对象的标识(在CPython中返回内存中对象的地址)

>>> tup = (1,"a",[1,2,3])
>>> tup
(1, 'a', [1, 2, 3])
>>> [id(x) for x in tup]
[36090200, 140119363921520, 140119362889416]
>>> tup[2][1] = 'a'
>>> tup
(1, 'a', [1, 'a', 3])
>>> [id(x) for x in tup]
[36090200, 140119363921520, 140119362889416]

答案 2 :(得分:0)

元组是不可变的 - 它总是包含相同的对象。如果这些对象是可变的,它们本身可能会发生变异,但元组仍将包含该对象。