是的,这是预期的。
元组不能更改。元组(如列表)是指向其他对象的结构。它不在乎那些对象是什么。它们可以是字符串,数字,元组,列表或其他对象。
因此,对元组中包含的对象之一执行任何操作(包括在列表中追加到该对象)都与元组的语义无关。
(想象一下,如果您编写了一个类,该类上具有导致其内部状态发生变化的方法。您不会期望不可能根据对象的存储位置在对象上调用这些方法)。
或另一个例子:
>>> l1 = [1, 2, 3]>>> l2 = [4, 5, 6]>>> t = (l1, l2)>>> l3 = [l1, l2]>>> l3[1].append(7)
一个列表和一个元组引用的两个可变列表。我是否应该能够做最后一行(答案:是)。如果您认为答案是否定的,为什么不呢?应该
t更改
l3(答案:否)的语义。
如果您想要一个不可变的顺序结构对象,那么它应该一直是元组。
为什么会出错?
本示例使用infix运算符:
许多操作都有“就地”版本。与通常的语法相比,以下函数提供了对原位运算符的更原始的访问;例如,语句x + = y等效于x =
operator.iadd(x,y)。另一种表达方式是说z = operator.iadd(x,y)等效于复合语句z = x; z + = y。
https://docs.python.org/2/library/operator.html
所以这:
l = [1, 2, 3]tup = (l,)tup[0] += (4,5,6)
等效于此:
l = [1, 2, 3]tup = (l,)x = tup[0]x = x.__iadd__([4, 5, 6]) # like extend, but returns x instead of Nonetup[0] = x
该
__iadd__行成功,并修改了第一个列表。因此,列表已更改。该
__iadd__调用返回的突变列表。
第二行尝试将列表分配回元组,这将失败。
因此,在程序结束时,列表已扩展,但是操作的第二部分
+=失败。有关详细信息,请参阅此问题。


![附加到元组中定义的列表-是bug吗?[重复] 附加到元组中定义的列表-是bug吗?[重复]](http://www.mshxw.com/aiimages/31/386250.png)
