购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.1 元组结构

元组是Python中常用的一种数据结构。元组由不同的元素组成,每个元素可以存储不同类型的数据,如字符串、数字甚至元组。元组是“写保护”的,即元组创建后不能再做任何修改操作,元组通常代表一行数据,而元组中的元素代表不同的数据项。

4.1.1 元组的创建

tuple(元组)是Python内置的一种数据结构。元组由一系列元素组成,所有元素被包含在一对圆括号中。创建元组时,可以不指定元素的个数,相当于不定长的数组,但是一旦创建后就不能修改元组的长度。元组创建的格式如下所示。


tuple = (元素1, 元素2, …)

元组的初始化示例如下:


tuple = ("apple", "banana", "grape", "orange")

上面这行代码创建了一个名为tuple的元组,该元组由4个元素组成,元素之间使用逗号分隔。

如果需要定义一个空的元组,表达方式更简单。创建空的元组只需要一对空的圆括号。


tuple = ()

如果创建的元组只包含一个元素,通常会错误地忽略单元素后的逗号。Python无法区分变量tuple是元组还是表达式,Python误认为圆括号中的内容为表达式,因此tuple[0]输出的结果并非期望的值,并且其类型也不是tuple。错误的写法如下:


01     tuple = ("apple")               # 定义元组
02     print(tuple[0])                  # 打印第一个元素
03     print (type(tuple))         # 打印定义的tuple的类型

运行这段代码并不会提示任何错误,代码将输出字母“a”,而不是期望的“apple”。并且其类型为<class‘str’>。正确的写法如下:


01     tuple = ("apple",)             # 定义元组,注意后面的逗号不可少
02     print (tuple[0])                # 打印第一个元素
03     print (type(tuple))             # 打印定义的tuple的类型

此时,将输出tuple元组中唯一的元素“apple”,并且类型为<class‘tuple’>。所以,创建一个唯一元素的元组,需要在元素的后面添加一个逗号,使Python能正确识别出元组中的元素。

注意 元组是从0开始计数的,因此tuple[0]获得的是元组tuple中第1个元素。Python中其他的数据结构也遵循这个规则。

4.1.2 元组的访问

元组中元素的值通过索引访问,索引是一对方括号中的数字,索引也称为“下标”。元组的访问格式如下。


tuple[n]

其中,tuple[n]表示访问元组的第n个元素,索引n的值可以为0、正整数或负整数。前面一节已经提到了元组的输出方法,例如:


print (tuple[1])

上面这行代码将输出字符串“banana”,print语句表示输出,tuple[1]表示访问tuple的第2个元素。

可以把元组理解为数组,使用C或Java语言编程的读者应该不会陌生,数组的下标是从0开始计数,而元组中元素的访问也符合这个规则。

元组创建后其内部元素的值不能被修改,如果修改元组中的某个元素,运行时将报错。例如:


tuple[0] = "a"

对tuple元组中第1个元素进行赋值,运行代码后错误信息如下:


TypeError: 'tuple' object does not support item assignment

可见,元组中的元素并不支持赋值操作。

注意 元组不能添加或删除任何元素。因此,元组不存在任何添加、删除元素的方法,元组也不存在任何其他方法。

元组的访问还有一些特殊的用法,这些用法对于获取元组的值非常方便,例如负数索引和分片索引。这两个特性是Python的特殊用法,C或Java语言并不支持。负数索引从元组的尾部开始计数,最尾端的元素索引表示“-1”,次尾端的元素索引表示“-2”,以此类推。图4-1演示了负数索引与元素的对应关系,tuple[-1]的值为value4,tuple[-2]的值为value3。

分片(slice)是元组的一个子集,分片是从第1个索引到第2个索引(不包含第2个索引所指向的元素)所指定的所有元素。分片索引可以为正数或负数,两个索引之间用冒号分隔。分片的格式如下所示:


tuple[m:n]

其中,m、n可以是0、正整数或负整数。

图4-2演示了分片索引与元素的对应关系,tuple[1:3]将返回(value2,value3,value4)。

图4-1 负数索引演示

图4-2 分片索引演示

下面【例4-1】这段代码将说明负数索引和分片索引的使用。

【例4-1.py】


01     tuple = ("apple", "banana", "grape", "orange")          # 定义元组
02     print (tuple[-1])                         # 分片,倒数第一个元素
03     print (tuple[-2])                         # 分片,倒数第二个元素
04     tuple2 = tuple[1:3]                   # 分片,第二个元素到第三个元素(不包括第四个)
05     tuple3 = tuple[0:-2]                   # 分片,从第一个元素到倒数第二个元素(不包括倒数第二个)
06     tuple4 = tuple[2:-2]                   # 分片,从第三个元素到倒数第二个元素(不包括倒数第二个)
07     print (tuple2)
08     print (tuple3)
09     print (tuple4)

【代码说明】

·元组的索引可以用负数表示,第2、3行代码将分别输出“orange”和“grap”。

·使用分片截取后,将得到一个新的元组。第4行到第6行代码分别创建了3个元组。

·tuple2输出结果:('banana','grape')

·tuple3输出结果:('apple','banana')

·tuple4输出结果:()

元组还可以由其他元组组成。例如,二元元组可以表示为:


tuple = (('t1', 't2'), ('t3', 't4'))

tuple是一个二元元组,该元组由('t1','t2')和('t3','t4')组成。

下面【例4-2】的代码说明了元组间的包含关系以及元组中元素的访问。

【例4-2.py】


01     fruit1 = ("apple", "banana")          # 定义fruit1元组
02     fruit2 = ("grape", "orange")          # 定义fruit2元组
03     tuple = (fruit1, fruit2)
04     print (tuple)
05     print ("tuple[0][1] =", tuple[0][1])
06     print ("tuple[1][1] =", tuple[1][1])
07     print ("tuple[1][1] =", tuple[1][2])

【代码说明】

·第3行代码创建了一个复合元组tuple,tuple由元组fruit1和fruit2组成。元组tuple的输出结果:


(('apple', 'banana'), ('grape', 'orange'))

·tuple[0][1]表示访问tuple元组中第1个元组的第2个元素,即fruit1元组中的第2个元素,可以把tuple理解为二维数组。tuple[0][1]输出结果:


tuple[0][1] = banana

·tuple[1][1]表示访问tuple元组中第2个元组的第2个元素,即fruit2元组中的第2个元素。tuple[1][1]输出结果:


tuple[1][1] = orange

·同理,tuple[1][2]将访问fruit2元组中的第3个元素,因为此元素不存在,元组的索引访问越界。运行后将输出如下错误信息:


IndexError: tuple index out of range

tuple元组的存储结构如图4-3所示。

图4-3 tuple元组的存储结构

创建元组的过程,Python称为“打包”。相反,元组也可以执行“解包”的操作。“解包”可以将包元组中的各个元素分别赋值给多个变量。这样,避免了使用循环遍历的方法获取每个元素的值,降低了代码的复杂性,使表达方式更自然。下面这个例子说明了元组“打包”和“解包”的过程。


01     #打包
02     tuple = ("apple", "banana", "grape", "orange")
03     #解包
04     a, b, c, d = tuple
05     print (a, b, c, d)

【代码说明】

·第2行代码创建了一个tuple元组,元组的创建即“打包”的过程。

·第4行代码使用了一个赋值操作,等号的右边是tuple元组,等号的左边有4个变量,元组tuple中的4个元素分别赋值给这4个变量。

·第5行代码输出4个变量的值,输出的结果如下:


apple banana grape orange

4.1.3 元组的遍历

元组的遍历是指通过循环语句依次访问元组中各元素的值。遍历元组需要用到两个函数range()和len()。range()和len()都是Python的内建函数,这些函数可直接调用,不需要import语句导入模块。内建函数是Python自动导入的函数,相当于Java中的lang包。

len()计算出tuple元组中元素的个数,range()返回一个由数字组成的列表,关于列表的概念请参考4.2节。range()的声明如下所示。


range([start,] stop[, step]) -> list of integers

【代码说明】

·range()返回一个递增或递减的数字列表,列表的元素值由3个参数决定。

·参数start表示列表开始的值,默认值为0。

·参数stop表示列表结束的值,该参数不可缺少。

·参数step表示步长,每次递增或递减的值,默认值为1。

例如,range(5)返回的列表为[0,1,2,3,4]。下面【例4-3】这段代码实现了二元元组的遍历。

【例4-3.py】


01     tuple = (("apple", "banana"),("grape", "orange"),("watermelon",),("grapefruit",))
02     for i in range(len(tuple)):
03         print ("tuple[%d] :" % i, end = ' ')
04         for j in range(len(tuple[i])):
05             print (tuple[i][j], end = ' ')
06         print()

【代码说明】

·第1行代码创建了一个由4个子元组组成的二元元组tuple。

·第2行到第6行代码遍历tuple元组,输出元组中各个元素的值。tuple元组的遍历结果:


tuple[0] :  apple  banana
tuple[1] :  grape  orange
tuple[2] :  watermelon
tuple[3] :  grapefruit

此外,也可以直接使用for…in语句遍历元组,代码如下:


01     tuple = (("apple", "banana"),("grape", "orange"),("watermelon",),("grapefruit",))
02     for i in tuple:      # 遍历元组tuple
03         for j in i:      # 同样对子元组进行遍历
04             print(j)   # 依次打印出元素

【代码说明】

·第1行同样创建了一个元组。

·第2行开始遍历元组tuple。

·第3行开始对各子元组进行遍历。

·第4行打印出元素。

遍历结果: 5ghYcrZ3rtheZ1yt3URCyv1ioIN30313UoeVceeigbyROT9xilmJ47PkrwlDWbqi


apple
banana
grape
orange
watermelon
grapefruit

点击中间区域
呼出菜单
上一章
目录
下一章
×