作者: 一去、二三里
个人微信号: iwaleon
微信公众号: 高效程序员
在 Python 中,元组(Tuple)与列表类似。两者之间的区别在于:元组不能更改,列表可以。也就是说,一旦被分配,就不能从元组中添加、更改或删除元素。
元组的优点
既然和列表类似,那元组的作用到底是什么呢?用列表代替不就可以了?
与列表相比,元组有很多优点:
- 通常将元组用于不同的数据类型,将列表用于相同(或相似)的数据类型。
- 由于元组不可变,所以遍历元组比列表要快(较小的性能提升)。
- 元组可以用作字典的 key,而列表不行。因为字典的 key 必须是不可变的,元组本身就是不可变的。
- 如果数据不需要更改,将其作为元组来实现,可以确保“写保护”。
- 元组可以被用在字符串格式化中。
元组
在 Python 中,元组由内置的 tuple 类型定义。
要创建元组,需要将所有项(元素)放在括号(()
)内,以逗号(,
)分隔。
注意: 括号是可选的,但还是建议写上。
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>> type(tup)
<class 'tuple'>
元组中的元素可以是任意数量,还可以是不同类型(例如:数字、字符串、列表等)。
>>> tup = () # 空元组
>>>
>>> tup = ('P', 'y', 't', 'h', 'o', 'n') # 字符串类型元组
>>>
>>> tup = (1, 5.5, 'Python') # 混合类型元组
>>
>>> tup = (6, 'Python', ('P', 'y', 't', 'h', 'o', 'n')) # 嵌套元组
>>>
>>> tup = 1, 5.5, 'Python' # 创建元组时可以没有括号,也称为元组包装
>>> tup
(1, 5.5, 'Python')
>>>
>>> a, b, c = tup # 元组解包
>>> a
1
>>> b
5.5
>>> c
'Python'
构造包含一个元素的元组比较特殊,括号内只包含一个元素是不够的,还需要在元素后添加一个逗号。
>>> tup = ('Python') # 只有括号
>>> type(tup)
<class 'str'>
>>>
>>> tup = ('Python',) # 在元素后面添加逗号
>>> type(tup)
<class 'tuple'>
可以看出,没有逗号就不是元组,加了逗号才是。
索引和切片
有了前面关于字符串和列表的基础知识,元组很容易掌握。因为它们都属于序列,因此,基本操作是一样的。
可以使用索引操作符([]
) 来访问元组中的一个元素,使用切片操作符(:
)来访问元组中的一系列元素。
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>>
>>> tup[0] # 第 1 个元素
'P'
>>>
>>> tup[-2] # 第 5 个元素(反向索引)
'o'
>>>
>>> tup = (6, 'Python', ('P', 'y', 't', 'h', 'o', 'n')) # 嵌套元组
>>>
>>> tup[2][3] # 嵌套索引
'h'
>>>
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>>
>>> tup[1:4] # 第 2 个到第 4 个元素
('y', 't', 'h')
>>>
>>> tup[:-3] # 开始到第 3 个元素
('P', 'y', 't')
其他的一些基本操作,例如:连接(+)、重复(*)、成员测试(in)、遍历(for)等,就不再一一展示了,请参考:Python 列表
更改元组
元组是不可变的,也就是说,元组中的元素在被赋值后不能改变。
但是,如果元素本身是一个可变数据类型的列表,那么其嵌套项可以被改变。
>>> tup = (6, 'Python', ['P', 'y', 't', 'h', 'o', 'n'])
>>>
>>> tup[0] = 8 # 不能改变元素
...
TypeError: 'tuple' object does not support item assignment
>>>
>>> tup[2][3] = 's' # 可变的元素可以被改变
>>> tup
(6, 'Python', ['P', 'y', 't', 's', 'o', 'n'])
删除元组
如上所述,不能更改元组中的元素,这也意味着无法删除元组中的元素。
但是,使用关键字 del
可以删除整个元组。
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>>
>>> del tup[2] # 无法删除元素
...
TypeError: 'tuple' object doesn't support item deletion
>>>
>>> del tup # 可以删除整个元组
>>> tup
...
NameError: name 'tup' is not defined
列表和元组互转
列表和元组之间可以进行相互转换,分别使用 list() 和 tuple() 实现:
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>> listx = list(tup)
>>> listx
['P', 'y', 't', 'h', 'o', 'n']
>>>
>>> l = ['H', 'e', 'l', 'l', 'o']
>>> tupx = tuple(l)
>>> tupx
('H', 'e', 'l', 'l', 'o')
既然可以互转,那么要改变元组,可以先将其转化为列表,对列表进行更改,然后再将列表转换为元组。
例如,删除元组中的元素:
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>> listx = list(tup) # 将元组转换为列表
>>> listx.remove('h') # 删除列表中的元素
>>> tup = tuple(listx) # 再将列表转换为元组
>>> tup
('P', 'y', 't', 'o', 'n')
注意: 元组本身是不可变的。这里说的并不是传统意义的改变,相当于元组的重新赋值。
元组的方法
元组中的方法相对较少,可以通过 dir() 来查看方法列表:
>>> dir(tuple)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
可以看到,有两个可用的方法:
方法 | 描述 |
---|---|
index() | 返回第一个匹配项的索引 |
count() | 统计某个元素在列表中出现的次数 |
使用很简单,也非常好记。
>>> tup = ('P', 'y', 't', 'h', 'o', 'n')
>>>
>>> tup.index('h') # 返回第一个匹配 'h' 的索引
3
>>>
>>> tup.count('o') # 统计 'o' 在元组中出现的次数
1
注意: 元组不可变,所以添加或删除元素的方法不适用于元组。
元组与内置函数
下述内置函数通常与元组一起使用,来执行不同的任务。
函数 | 描述 |
---|---|
all() | 如果元组中的所有元素都是 True(或者元组为空),则返回 True。 |
any() | 如果元组中的所有元素都是 True,则返回 True;如果元组为空,则返回 False。 |
enumerate() | 返回一个枚举对象,其中包含了元组中所有元素的索引和值(配对)。 |
len() | 返回元组的长度(元素个数) |
max() | 返回元组中的最大项 |
min() | 返回元组中的最小项 |
sorted() | 返回一个新的排序元组(不排序元组本身) |
sum() | 返回元组的所有元素之和 |
tuple() | 将 iterable(字符串、列表、集合、字典)转换为元组 |