![Python基础及应用](https://wfqqreader-1252317822.image.myqcloud.com/cover/836/41309836/b_41309836.jpg)
4.2 Tuple(元组)
Tuple又叫元组,是一个线性结构,它的表达形式是这样的:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/72_01.jpg?sign=1738821313-AXn6cOMYKwaPBMRjszBCeNXq9Wq4IvbZ-0-9d8d9c66d368b1533e5c6597c6c796c3)
即用一个圆括号括起来的一串对象就可以创建一个Tuple,之所以说它是一个线性结构是因为在元组中元素是有序的,比如我们可以这样去访问它的内容:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/72_02.jpg?sign=1738821313-Fx1tNozc23aMMOwGzCNhd3wIy97IuftG-0-2ea8675b1432adbb89a21f1ebdc4ec5a)
这段代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/72_03.jpg?sign=1738821313-5b5bBtk4nIJBtXEMcIfE0fcbZdbwuCbY-0-ff4491f1e97a63dee9e8095e4d2b3d88)
这里可以看到,我们通过“[]”运算符直接访问了Tuple的内容,这个运算符在上一章已经见过了,但是没有深入讲解。这里先详细学习切片操作符,因为它是一个非常常用的运算符,尤其在Tuple和List中应用广泛。
4.2.1 切片
1.背景
切片操作符和C/C++的下标运算符非常像,但是在C/C++中,“[]”只能用来取出指定下标的元素,所以它在C/C++中叫作下标运算符。
在Python中,这个功能被极大地扩展了——它不但能取一个元素,还能取一串元素,甚至还能隔着取、倒着取、反向取等。由于取一串元素的操作更像是在切片,所以我们称它为切片操作符。
灵活使用切片操作符,往往可以大大简化代码,这也是Python提供的便利之一。
2.取一个元素
如果有一个Tuple,并且我们想取出其中一个元素,可以使用具有一个参数的下标运算符:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/72_04.jpg?sign=1738821313-Og10B457387c5oRTFcqprKlZuU57Kgap-0-96e625b37526996048798b9670dac728)
绝大部分编程语言下标都是从0开始的,也就是说在Python中对于一个有n个元素的Tuple,自然数下标的范围是0~n-1。
所以这里会输出tuple1中下标为2的第3个元素:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_01.jpg?sign=1738821313-Qiqxc5zsAphH2KtxS69s3zGFbUnqZYc4-0-09729479607bd0edefa76ec15bf03ad1)
这是切片操作符最简单的形式,它只接收一个参数就是元素的下标,也就是上面例子里的2。
特别地,Python支持负数下标表示从结尾倒着取元素,比如如果想取出最后一个元素:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_02.jpg?sign=1738821313-x98XVEx1WIGyMTo2VtBtBnus6puYcaPB-0-83de431398aeb89c1b2683ac4de1b079)
但是要注意的是负数下标是从-1开始的,所以对于一个含有n个元素的Tuple,它的负数下标范围为-1~-n,因此这里得到的是下标为4的最后一个元素,输出为:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_03.jpg?sign=1738821313-Kollc6hJUcAlE9m6yS3YlhwJvgHCGXSL-0-9e750132a5ee83b2bde88ff0a79af1bd)
如果我们取了一个超出范围的元素:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_04.jpg?sign=1738821313-DgCxspk1oR9NJ06UDypoAQkcxHLPWWxO-0-b50c7bf0ba0369864770d29ef8d721d9)
那么Python解释器会抛出一个IndexError异常:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_05.jpg?sign=1738821313-AMXbZdbSb6W9g509XVCUxwayScAedynt-0-18442e227cf23d7aed93a5f4a078ff12)
这个异常的详细信息是下标超出了范围。如果遇到这种情况,需要检查一下代码是不是访问了不存在的下标。
3.取连续的元素
先看一个例子:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_06.jpg?sign=1738821313-Ng2DLebEjFqgt6T0ayOQ9j7ngnZSpQfU-0-b27649046ff6fd4053dc9d419a914675)
这段代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_07.jpg?sign=1738821313-VteFsrKrHtnlNpAgfSmiiAHHGR2672QM-0-a4533189acd2366fa9998673dc3c004c)
我们会发现结果仍然是一个Tuple,由第1个到第4个元素之间的元素构成,其中包含第1个元素,但是不包含第4个元素。
这种切片操作接收两个参数,开始下标和结束下标,中间用分号隔开,也就是上面例子中的0和3,但是要注意的是元素下标区间是左闭右开的。如果对之前讲循环时候的range还有印象的话,可以发现它们的区间都是左闭右开的,这是Python中的一个规律。
特殊地,如果从第0个元素开始取,或者要一直取到最后一个,我们可以省略相应的参数,比如:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/73_08.jpg?sign=1738821313-0xvgVpNARBaXC9gus8XJiOr4iHBdXJMS-0-aa750cefbed77fdb96c88f820d86487f)
第一句表示从第1个元素取到第3个元素,第二句表示从第4个元素取到最后一个元素,所以输出为:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_01.jpg?sign=1738821313-scNGz5UxiAfzTEacjXciqr5ooNYbsSqh-0-7f57470af8f44f5912c3a589fec29e5b)
同样地,这里也可以使用负下标,比如:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_02.jpg?sign=1738821313-pjs0YWkxO1edkAMnvHzJ3VWss4Rd7PxX-0-6a47c76952e2e54eaf1e10a9bba2d7d0)
表示从第1个元素取到倒数第2个元素,所以输出为:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_03.jpg?sign=1738821313-raJwHc0lPyS3VEnMzNXNpas1QnCUCnJq-0-23ccc9e03e5bf766924ea8bc8fa8063f)
4.以固定间隔取连续的元素
上述取连续元素的操作其实还可以进一步丰富,比如下面这个例子:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_04.jpg?sign=1738821313-rCy7g0wrarSDnu3EtAO6CXBEv76UvC4K-0-6d2fb10259bd1e657765e417543079c3)
这段代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_05.jpg?sign=1738821313-7uvksjbeUIdvA0AtP1QHHBy0JD5Qm4Ni-0-ba621764abca9417a6fd461840ff7550)
这里表示的含义就是从第2个元素取到第5个元素,每2个取第1个元素。于是我们取出了第2个和第4个元素。这也是切片操作符的完整形式,即[开始:结束:间隔],例如上面的[1:4:2]。
特殊地,这个间隔可以是负数,表示反向间隔,例如:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_06.jpg?sign=1738821313-FuKzaiUnAoZ7sD5jkOG6PP3RAVqihF8j-0-8dc8372b7bd3dc83fc9cc9efcb18f5b3)
这句代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_07.jpg?sign=1738821313-SgSRHBtOsOoPt2jy27Y0e52uVrQdKdlD-0-a364526409ec44ee94a89c2e9264463e)
可以看出就是翻转了整个Tuple。
4.2.2 修改
这里说的“修改”并不是原位的修改,因为Tuple的元素一旦指定就不可再修改,而是通过创建一个新的Tuple来实现修改,比如下面这个例子:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_08.jpg?sign=1738821313-FKi7rb7LCWCkUQL1cZN1pWJyrm2ZgQe4-0-c414fc6f544692c09197d689ea3f9013)
这段代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/74_09.jpg?sign=1738821313-kNGUVXkbPSYkQ3lLN404rlFOPIN0qBFK-0-280cb4bd8bbcd685db145a9df5e34104)
可以看到我们通过创建tuple3和tuple4,“修改”了tuple1和tuple2。
同时要注意的是,之前在讲字符串的时候提到的加法和乘法对Tuple的操作也是类似的,效果分别是两个Tuple元素合并为一个新的Tuple和重复自身元素返回一个新的Tuple。
4.2.3 遍历
遍历有两种方法:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/75_01.jpg?sign=1738821313-QeFIPOi440GysmSctkAoZqGQP2o7ZH6C-0-0e20b3c6cee4c40304a44f48e89c0128)
这段代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/75_02.jpg?sign=1738821313-6SsgO9oiMC9igHNlturD29PFT8IKjeDR-0-f8647845a04462c4ecded8bb7143000b)
这里,在print函数中加了一个使结束符为空的参数,这个用法会在下一章函数中讲到,这里只要知道这样会使print不再自动换行就可以了。
我们可以通过一个for循环或者while循环直接顺序访问元组的内容。显然for循环不仅可读性高而且更加简单,在大多数情况下应该优先采用for循环。
另外值得一提的是,之所以Tuple可以这样用for遍历是因为Tuple包括后面马上要提到的List和Dict对象本身是可迭代的对象,这个概念之后会细讲,这里只要学会for循环的用法就可以了。
4.2.4 查找
在Tuple中查找元素可以用in,比如:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/75_03.jpg?sign=1738821313-jaGjFC2UFtKT1n3gYCw64OPA55Tv6eyQ-0-0773cc96787e7389ad668a8893ae94c9)
这段代码会输出:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/75_04.jpg?sign=1738821313-1GPJ8oddxFlzOOHDbH6PJUUwVDwf8RM0-0-95e87b50dd3c9a98594dc6757d9086d6)
in是一个使用广泛的用于判断包含的运算符,类似地还有not in。in的作用就是判断特定元素是否在某个对象中,如果包含就返回True,否则返回False。
4.2.5 内置函数
此外有一些内置函数可以作用于Tuple上,比如:
![](https://epubservercos.yuewen.com/82BE21/21511156608178806/epubprivate/OEBPS/Images/76_01.jpg?sign=1738821313-bs2OiCHKcxE7iu1qC10koFzOE1PMTNUW-0-e92f67d55d444dab34199d018a874e67)
从上到下分别是求tuple1的长度、tuple1中最大的元素、tuple2中最小的元素。
这些函数对接下来即将讲到的List和Dict也有类似的作用。