Python系列 11 线性容器序列(tuple)

元组Python中的元组容器序列(tuple)与列表容器序列(list)具有极大的相似之处,因此也常被称为不可变的列表。但是两者之间也有很多的差距,元组侧重于数据的展示,而列表侧重于数据的存储与操作。它们非常相似,虽然都可以存储任意类型的数据,但是一个元组定义好之后就不能够再进行修改。元组特性元组特性如下:元组属于线性容器序列元组属于不可变类型,即对象本身的属性不会根据外部变化而变化元组底层由顺序存储组成,而顺序存储是线性结构的一种基本声明以下是使用类实例化的形式进行对象声明:tu
摘要由CSDN通过智能技术生成

元组

Python中的元组容器序列(tuple)与列表容器序列(list)具有极大的相似之处,因此也常被称为不可变的列表。

但是两者之间也有很多的差距,元组侧重于数据的展示,而列表侧重于数据的存储与操作。

它们非常相似,虽然都可以存储任意类型的数据,但是一个元组定义好之后就不能够再进行修改。

元组特性

元组特性如下:

  1. 元组属于线性容器序列
  2. 元组属于不可变类型,即对象本身的属性不会根据外部变化而变化
  3. 元组底层由顺序存储组成,而顺序存储是线性结构的一种

基本声明

以下是使用类实例化的形式进行对象声明:

tpl = tuple((1, 2, 3, 4, 5))
print("value : %r\ntype : %r" % (tpl, type(tpl)))

# value : (1, 2, 3, 4, 5)
# type : <class 'tuple'>

也可以选择使用更方便的字面量形式进行对象声明,使用逗号对数据项之间进行分割:

tpl = 1, 2, 3, 4, 5
print("value : %r\ntype : %r" % (tpl, type(tpl)))

# value : (1, 2, 3, 4, 5)
# type : <class 'tuple'>

为了美观,我们一般会在两侧加上(),但是要确定一点,元组定义是用逗号来分隔数据项,而并非是用()包裹数据项:

tpl = (1, 2, 3, 4, 5)
print("value : %r\ntype : %r" % (tpl, type(tpl)))

# value : (1, 2, 3, 4, 5)
# type : <class 'tuple'>

多维元组

当一个元组中嵌套另一个元组,该元组就可以称为多维元组。

如下,定义一个2维元组:

tpl = (1, 2, ("三", "四"))
print("value : %r\ntype : %r" % (tpl , type(tpl)))

# value : (1, 2, ('三', '四'))
# type : <class 'tuple'>

续行操作

在Python中,元组中的数据项如果过多,可能会导致整个元组太长,太长的元组是不符合PEP8规范的。

  • 每行最大的字符数不可超过79,文档字符或者注释每行不可超过72

Python虽然提供了续行符\,但是在元组中可以忽略续行符,如下所示:

tpl = (
    1,
    2,
    3,
    4,
    5
)
print("value : %r\ntype : %r" % (tpl, type(tpl)))

# value : (1, 2, 3, 4, 5)
# type : <class 'tuple'>

类型转换

元组支持与布尔型、字符串、列表、以及集合类型进行类型转换:

tpl = (1, 2, 3)
bTpl = bool(tpl)
strTpl = str(tpl)
lstTpl = list(tpl)
setTpl = set(tpl)

print("value : %r\ntype : %r" % (bTpl, type(bTpl)))
print("value : %r\ntype : %r" % (strTpl, type(strTpl)))
print("value : %r\ntype : %r" % (lstTpl, type(lstTpl)))
print("value : %r\ntype : %r" % (setTpl, type(setTpl)))

# value : True
# type : <class 'bool'>
# value : '(1, 2, 3)'
# type : <class 'str'>
# value : [1, 2, 3]
# type : <class 'list'>
# value : {1, 2, 3}
# type : <class 'set'>

如果一个2维元组遵循一定的规律,那么也可以将其转换为字典类型:

tpl = (("k1", "v1"), ("k2", "v2"), ("k3", "v3"))
dictTuple = dict(tpl)

print("value : %r\ntype : %r" % (dictTuple, type(dictTuple)))

# value : {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
# type : <class 'dict'>

索引操作

元组由于是线性结构,故支持索引和切片操作

但只针对获取,不能对其内部数据项进行修改。

使用方法参照列表的索引切片一节。

绝对引用

元组拥有绝对引用的特性,无论是深拷贝还是浅拷贝,都不会获得其副本,而是直接对源对象进行引用。

但是列表没有绝对引用的特性,代码验证如下:

>>> import copy
>>> # 列表的深浅拷贝均创建新列表...
>>> oldLi = [1, 2, 3]
>>> id(oldLi)
4542649096
>>> li1 = copy.copy(oldLi)
>>> id(li1)
4542648840
>>> li2 = copy.deepcopy(oldLi)
>>> id(li2)
4542651208
>>> # 元组的深浅拷贝始终引用老元组
>>> oldTup = (1, 2, 3)
>>> id(oldTup)
4542652920
>>> tup1 = copy.copy(oldTup)
>>> id(tup1)
4542652920
>>> tup2 = copy.deepcopy(oldTup)
>>> id(tup2)
4542652920

Python为何要这样设计?其实仔细想想不难发现,元组不能对其进行操作,仅能获取数据项。

那么也就没有生成多个副本提供给开发人员操作的必要了,因为你修改不了元组,索性直接使用绝对引用策略。

值得注意的一点:[:]也是浅拷贝,故对元组来说属于绝对引用范畴。

元组的陷阱

Leonardo Rochael在2013年的Python巴西会议提出了一个非常具有思考意义的问题。

我们先来看一下:

>>> t = (1, 2, [30, 40])
>>> t[-1] += [50, 60]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' o
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值