跳转至

2.7.Tuple

Windows 10
Python 3.7.3 @ MSC v.1915 64 bit (AMD64)
Latest build date 2020.11.22

tuple 是一种一维的、不可变的 Python 对象序列,元素写在小括号 () 里,元素之间用逗号隔开,元组中的元素类型可以不相同。其名称来自拉丁语中与倍数有关的单词的后缀:double, triple, quadpleple, quinpleple。

不可变是指 tuple 对象创建之后,该 tuple 对象已包含的元素不能被修改或删除,也不能添加新元素。虽然 tuple 是不可变对象,但它可以包含可变的对象,比如一个 tuple 对象包含一个 list 对象。

不可变的tuple有什么意义?

对于某些操作,不可变的元组对象比可变列表对象更有效或更安全。创建元组后,只能对其进行访问,不必担心其中的元素被意外地修改。

最重要的是,元组可以可靠地哈希为某个值,因此可以作为映射类型的键。

陷阱——1个元素的Tuple

定义个一个Tuple,需要传入一个iterable对象。

tuple("123")
('1', '2', '3')

如果需要定义一个空的Tuple,可以通过tuple类来定义:

a = tuple()
type(a)
tuple

或者用 () 定义:

a = ()
type(a)
tuple

但是如果要定义只有一个元素的tuple,就要注意了。如果这样定义,则是错误的:

b = ("123")
type(b)
str

定义只有一个元素的tuple,需要这样定义:

b = ("123",)
type(b)
tuple

或者这样定义:

b = tuple(["123"])
type(b)
tuple

为什么会这样呢?因为()在 Python 中可以表示运算符的(),也可以表示Tuple。这就不可避免地产生了歧义,为了消除歧义,Python规定括号里面只有一个元素时,按运算符的()进行解析。

陷阱——“可变的”Tuple

前面说过,Tuple是一种不可变的对象。但是有时我们又会发现Tuple是“可变的”。

c = ('a', 'b', ['A', 'B'])
print("原始的Tuple:",c)
c[2][0] = 'X'
c[2][1] = 'Y'
print("修改后的Tuple:",c)
原始的Tuple: ('a', 'b', ['A', 'B'])
修改后的Tuple: ('a', 'b', ['X', 'Y'])

前面说过tuple一旦定义后就不可变,那上面的c怎么就改变了呢?其实,c的元素并没有改变,改变的只是list中的元素,tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素的指向永远不变。即指向a,就不能改成指向b,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!

所以要创建一个内容也不变的tuple,那就必须保证tuple的每一个元素本身也不能变。

方法

因为Tuple是一个不可变的列表,没有用于修改列表的方法,所以Tuple对象的方法很少。

d = (0,1,2,3,4,4)
[method for method in dir(d) if not method.startswith("_")]
['count', 'index']

统计元素出现的次数

d.count(4)
2

元素第一次出现时对应的索引值

d.index(4)
4