【Python学习手册(第四版)】学习笔记09.1-Python对象类型-元组

个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。


目录

元组

元组操作

实际应用

元组的特殊语法:逗号和圆括号

转换、方法以及不可变性

index、count及其他方法

有了列表为什么还要元组


元组

元组(tuple)由简单的对象组构成。元组与列表非常类似,只不过元组不能在原处修改(它们是不可变的),并且通常写成圆括号(而不是方括号)中的一系列项。

元组不支持任何方法调用,但元组具有列表的大多数属性。

任意对象的有序集合

与字符串和列表类似,元组是一个位置有序的对象的集合(也就是其内容维持从左到右的顺序)。与列表相同,可以嵌入到任何类别的对象中。

通过偏移存取

同字符串、列表一样,在元组中的元素通过偏移(而不是键)来访问。它们支持所有基于偏移的操作。例如,索引和分片。

属于不可变序列类型

类似于字符串,元组是不可变的,它们不支持应用在列表中任何原处修改操作。与字符串和列表类似,元组是序列,它们支持许多同样的操作。

固定长度、异构、任意嵌套

元组是不可变的,在不生成一个拷贝的情况下不能增长或缩短。另一方面,元组可以包含其他的复合对象(例如,列表、字典和其他元组等)

对象引用的数组

与列表相似,元组最好看做是对象引用的数组。元组存储指向其他对象的存取点(引用),并且对元组进行索引操作的速度相对较快。

元组操作

元组编写为一系列对象(从技术上来讲,是生成对象的表达式),用逗号隔开,并且用圆括号括起来。一个空元组就是一对内空的括号。

实际应用

在表9-1中,元组没有方法(例如,append调用在这是不可用的)。然而,元组的确支持字符串和列表的一般序列操作。

>>> (1,2) + (3,4)
(1, 2, 3, 4)
>>> (1,2) * 4
(1, 2, 1, 2, 1, 2, 1, 2)
>>> t = (1,2,3,4)
>>> t[0],t[1:3]
(1, (2, 3))

元组的特殊语法:逗号和圆括号

如果圆括号里的单一对象是元组对象而不是一个简单的表达式,需要对Python进行特别说明。如果确实想得到一个元组,只要在这一单个元素之后、关闭圆括号之前加一个逗号就可以了。

作为特殊情况,在不会引起语法冲突的情况下,Python允许忽略元组的圆括号。

>>> x = 40
>>> x
40
>>> type(x)
<class 'int'>

>>> y = 40,
>>> y
(40,)
>>> type(y)
<class 'tuple'>

>>> z = (40,)
>>> z
(40,)
>>> type(z)
<class 'tuple'>

对初学者而言,最好的建议是一直使用圆括号,这可能会比弄明白什么时候可以省略圆括号要更简单一些。许多程序员也发现圆括号有助于增加脚本的可读性,因为这样可以使元组更加明确,尽管你的使用经验可能会有所不同。

转换、方法以及不可变性

除了常量语法不同以外,元组的操作(表9-1的中间行)和字符串及列表是一致的。值得注意的区别在于“+”、“*”以及分片操作应用于元组时将返回新元组,并且元组不提供字符串、列表和字典中的方法。

例如,如果你想对元组进行排序,通常先得将它转换为列表并使其成为一个可变对象,才能获得使用排序方法调用的权限,或者使用sorted内置方法,它接受任何序列对象(以及更多):

>>> t = ('a','z','c','b')
>>> tmp = list(t)
>>> tmp
['a', 'z', 'c', 'b']
>>> tmp.sort()
>>> tmp
['a', 'b', 'c', 'z']

>>> tu = tuple(tmp)
>>> tu
('a', 'b', 'c', 'z')

>>> sorted(t)
['a', 'b', 'c', 'z']
>>> t
('a', 'z', 'c', 'b')

这里的列表和元组内置函数用来将对象转换为列表,之后返回为一个元组。实际上,这两个调用都会生成新的对象,但结果就像是转换。

列表解析(List comprehension)也可用于元组的转换。

例如,下面这个由元组生成的列表,过程中将每一项都加上20:

>>> t1 = (1,2,3)
>>> l1 = [x + 20 for x in t1]
>>> l1
[21, 22, 23]

列表解析是名副其实的序列操作——它们总会创建新的列表,但也可以用于遍历包括元组、字符串以及其他列表在内的任何序列对象。

列表解析甚至可以用在某些并非实际储存的序列之上——任何可遍历的对象都可以,包括可自动逐行读取的文件

注意元组的不可变性只适用于元组本身顶层而并非其内容。例如,元组内部的列表是可以像往常那样修改的。

>>> t[1] = 'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

>>> t[1][0] = 'a'
>>> t
(1, ['a', 3], 4)

对多数程序而言,这种单层深度的不可变性对一般元组角色来说已经足够了。

index、count及其他方法

index和count就像对列表一样工作,但是,它们也针对元组对象定义了:

>>> t2 = (1,2,3,4,5,11,22,33,1,2)

>>> t2.index(1)    #查询出第一次出现的偏移量 
0
>>> t2.index(33)
7
>>> t2.index(2,2)    #查询出第二次出现的偏移量
9
>>> t2.index(33,2)
7
>>> t2.index(33,3)
7
>>> t2.index(1,2) 
8
>>> t2.count(1)    #统计总数
2
>>> t2.count(33)
1
>>> t2
(1, 2, 3, 4, 5, 11, 22, 33, 1, 2)
>>> len(t2)    #长度
10
>>> min(t2)    #最小
1
>>> max(t2)    #最大
33
>>> del t2    #删除
>>> t2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 't2' is not defined

有了列表为什么还要元组

初学者学习元组的时候,这似乎总是第一个出现的问题——既然已经有列表了,为什么还需要元组?

历史性原因是:Python的创造者接受过数学训练,并提到过把元组看做是简单的对象组合,把列表看成是随时间改变的数据结构。实际上,单词“元组”就借用自数学领域,它通常用来指关系数据库表的一行。

最佳答案似乎是元组的不可变性提供了某种完整性。这样你可以确保元组在程序中不会被另一个引用修改,而列表就没有这样的保证了。

元组的角色类似于其他语言中的“常数”声明,然而这种常数概念在Python中是与对象相结合的,而不是变量。

元组也可以用在列表无法使用的地方。例如,作为字典键。一些内置操作可能也要求或暗示要使用元组而不是列表,尽管这样的操作往往已经通用化了。

总的来说:列表是定序集合的选择工具,可能需要进行修改,而元组能够处理其他固定关系的情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兴焉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值