python元组是不可变的--那么为什么我可以向它添加元素?

10 人关注

我使用Python已经有一段时间了,今天在阅读下面的代码片断时。

>>> a = (1,2)
>>> a += (3,4)
(1, 2, 3, 4)

我问了自己一个问题:为什么Python元组是不可变的,而我可以对它们使用+=操作符(或者,更广泛地说,为什么我可以修改一个元组)?我无法回答我自己。

我明白不可变性的想法,而且,尽管它们不像列表那样流行,但图元在python中还是很有用的。但在我看来,不可变性和能够修改长度是矛盾的......

1 个评论
@ColonelPanic 是的,有点类似的问题
python
tuples
immutability
ducin
ducin
发布于 2013-09-26
3 个回答
Veedrac
Veedrac
发布于 2013-09-26
已采纳
0 人赞同

5 也是不可变的。当你有一个不可变的数据结构时, a += b 等同于 a = a + b ,所以一个新的数字、元组或其他东西被创建。

当对易变结构做此操作时,结构是 改变了 .

>>> tup = (1, 2, 3)
>>> id(tup)
140153476307856
>>> tup += (4, 5)
>>> id(tup)
140153479825840

See how the id 改变了? That means it's a different object.

现在有了list,它是可变的。

>>> lst = [1, 2, 3]
>>> id(lst)
140153476247704
>>> lst += [4, 5]
>>> id(lst)
140153476247704

替换代码4】也是这么说的。

好的,所以我仍然不能向现有的元组添加一个元素(这使得它真正的不可改变),但是一个新的对象是在另外两个对象的基础上创建的--是这样吗?
tuple:: += 是用两个元组来创建第三个元组,即结果元组。似乎它与 list:: += 不同。- 似乎与 list:: += 不同,因为如果它做同样的事情(并创建第三个列表),那是合乎逻辑的。但是 lst + [4,5] 实际上是做了两次append。为什么 list::+= 不跟随 tuple::+=
因为一个 list += 是在原地的。更多的是 "为什么 tuple 不做 list 做的事",答案是 "它不能"。
我以为 += 操作符对每种序列类型的工作方式是一样的。或者至少对图元和列表是这样。谢谢你的解释,它是完全不同的:)。
@tkoomzaaskz: "为什么list::+=不跟随tuple::+=" -- 好问题。对于 list a += b not 相当于 a = a + b 。有些人可能会认为这很混乱,但他们可能不会像人们在 list+= 的情况下那样感到困惑,或者说不会经常感到困惑。 didn't 做一个就地的追加。最终的问题是,当 a b 具有 "值语义 "时, a += b a = a + b 之间的 "固有 "等价关系成立。但是 Python 变量没有值语义,它们有引用语义。也就是说,在Python中,变量指的是一个对象,它不包含一个值。
BrenBarn
BrenBarn
发布于 2013-09-26
0 人赞同

替换代码0】是否就地修改了对象,取决于对象。 对于元组,你并没有修改对象,如果你创建另一个指向同一对象的变量,你就可以看到。

>>> x = (1, 2)
>>> y = x
>>> x += (3, 4)
(1, 2)

对于易变的对象,如列表,你会看到值的变化,显示在它的所有名称下。

>>> x = [1, 2]
>>> y = x
>>> x += [3, 4]
[1, 2, 3, 4]