Python中的元组是否不可变?

3

它说:

一旦创建元组,就无法以任何方式更改。

但是当我执行以下操作时:

t1=(4,5,8,2,3)
t1=t1+(7,1)
print(t1)

元组正在更改为(4, 5, 8, 2, 3, 7, 1); 为什么会这样?"元组是不可变的"真正意味着什么?


9
执行此代码时没有损坏任何元组。 - tdelaney
t=2; t=t+5 不是将数字2变成7,而是创建一个新的数字;-) - Daniel
1
@tdelaney:恐怕在这段代码之后,原始元组的生命不会太长。程序员很少停下来思考他们的程序不再需要的旧对象。这些旧对象没有被送到任何养老院... - DrV
5个回答

9

是的,元组是不可变的;一旦创建,就不能更改。 t1=t1+(7,1) 创建一个新元组并将其赋值给名称t1。它不会更改最初由该名称引用的元组对象。

演示:

>>> t = (1, 2, 3)
>>> id(t)
4365928632
>>> t = t + (4, 5)
>>> id(t)
4354884624 # different id, different object

仅针对OP的一点说明:您可以将变量名称视为贴在元组上的标签,而您的赋值只是将相同的标签放置在新元组上。 - OBu

3
在你的代码中没有元组发生改变。name t1 被指向一个新的、独立的元组。原始的元组对象从未改变,你只是停止使用它了。

2

是的,它们是不可变的。

t1 = t1 + (7,1)

创建一个新元组而不是修改旧元组是否可行?

请尝试。

t1[0] = 5

2

当你调用t1=t1+(7,1)时,你正在重新分配t1到另一个内存位置。Python所说的不可变是指你不能通过切片来改变它们:

>>> t1=(4,5,8,2,3)
>>> t1[0] = 9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> 

因为这会创建一个新的元组:

>>> t1=(4,5,8,2,3)
>>> id(t1)
4467745808
>>> t1 = t1+(9,)
>>> id(t1)
4468302112
>>> 

正如您在列表中所看到的,它们会保留id

>>> lst = [4, 5, 8, 2, 3]
>>> id(lst)
4468230480
>>> lst[0] = 6
>>> id(lst)
4468230480
>>> 

那是Python对于“不可变性”的定义。

0

我不得不说“No”。

Python元组有一个让人惊讶的特性:它们是不可变的,但它们的值可能会改变。这可能发生在一个元组持有对任何可变对象(如字典、列表等)的引用时...

>>> t1 = ('Bangalore', ['HSR', 'Koramangala'])
>>> print(t1)
('Bangalore', ['HSR', 'Koramangala'])
>>> print(id(t1)) # ID of tuple
4619850952

>>> place = t1[1]
>>> place.append('Silk Board')  # Adding new value to the list
>>> print(t1) 
('Bangalore', ['HSR', 'Koramangala', 'Silk Board'])
# Surprisingly tuple changed, let's check the ID
>>> print(id(t1)) # No change in the ID of tuple
4619850952

>>> print(t1[0])
Bangalore
>>> print(id(t1[0])) # ID of tuple's first element
4641176176
>>> print(id(t1[1])) # ID of tuple's second element (List)
4639158024
# These are the ref. id's of the tuple

>>> place.append('Agara')
>>> print(t1) 
('Bangalore', ['HSR', 'Koramangala', 'Silk Board', 'Agara'])
>>> print(id(t1))
4619850952
# Still no change, are they Immutable ??

>>> print(id(t1[1])) # The tuple having a ref. of Mutable object
4639158024

在上面的例子中,元组和列表的ID没有改变。这是由于引用映射到元组而不是值所导致的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接