大家好,今天我们来学习一下,python数据类型之元组。
元组简介
元组是python内置数据类型之一,属于不可变数据类型。
说起元组和列表的区别,我们定会郎朗上口,嘻嘻~
- 元组的元素是不可更改的
- 元组没有添加/修改/删除元素的方法,只有索引访问、切片等通用操作
- 元组与列表一样可以进行比较、连接、计数操作
元组与列表常用方法的对照表如下:
元组与列表进行了一番对比之后,我们很疑惑,列表的功能比元组多,哪为什么还会出现元组这个数据类型呢
元组的存在,肯定是有道理的
一番查找,阅读资料后,果然发现了元组的“小秘密”,开心到飞起
简单汇总一下发现的结果:
- 元组不可变的特点,对于代码来说更安全
- 元组无删除/添加元素的功能,使它效率更高
- 元组具有灵活便捷的特性,在函数传参及返回值应用中尤为突出。
不可变
元组的不可变性,意味着可以使用python内置函数hash()进行hash处理。因此它是hashable的。类似与集合、字典的key,它们内部都是通过hash后的数据存放的。
因此,元组可以在集合、字典里充当key的,来优化我们的代码。
# 原数据
a = ["Bob","girl",19,"Tom","boy",20,"Bob","boy",15]
#可以使用元组来进行优化,使得数据具有唯一性
a= {
("Bob","girl"):19,
("Tom","boy"):20,
("Bob","boy"):15
}
效率高
元组无添加、删除元素的操作,这个使它的性能比list高。
创建 tuple 比 list 要快,存储空间比 list 占用更小。
所以就出现了“能用 tuple 的地方就不用 list”的说法。
import time
t1 = time.perf_counter()
# 创建一个元组
a = (1,2,3) #1.000000000001e-06
# 创建-个列表
a = [1,2,3] #1.1000000000038757e-06
print(time.perf_counter()-t1)
灵活便捷
元组灵活便捷性主要体现在我们函数方法的传参和返回值上。
尤其是支持函数返回多个值上,极大的方便了我们获取值。
# 创建一个函数方法
def setinfo(name,age):
return name,age
info = setinfo("ANNE",10)
print(info)
print(type(info))
1.创建元组
1.1 使用括号创建
可以使用()来创建元组。小括号可以省略
# 定义一个元组
t = ("a",5,[10,20])
# 打印元组
print(t)
print(id(t)) #2384909090072
元组内存分布情况:
更改元组t[2]里面的值后:
# 定义一个元组
t = ("a",5,[10,20])
t[2][0] = 30
t[2][1] = 40
# 打印元组
print(t)
print(id(t)) #2384909090072
注解:
- Tuple一开始指向的list并没有改成别的list。
- 指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的
- 我们此次更改就是元组指向list对象里面的值,没有违法元组的规则,所有程序正常运行。
特殊提示:
- 无小括号创建元组,示例如下:
# 创建一个元组
t = "a",5,[10,20]
# 打印元组
print(t)
- 如果只有一个元素时,元素后面必须要带逗号。
原因是python解释器会为整数或者字符串。
#只有一个元组
t = "a",
t2 = "a"
#分别打印
print(t)
print(type(t))
print(t2)
print(type(t2))
1.2 使用tuple()创建
tuple(可迭代对象)
tuple()将可迭代的对象如列表、字符串转换成元组
# 使用tuple()函数创建
t = tuple() # 空的元组对象
>>> t = tuple([10,20,30])
>>> t
(10, 20, 30)
>>> t1 = tuple("abc")
>>> t1
('a', 'b', 'c')
>>>
使用range()函数,生成可迭代对象
>>> t2 = tuple(range(3))
>>> t2
(0, 1, 2)
>>>
总结:
tuple()是可以接收列表、字符串、其他序列类型、迭代器等生成元组
list()是可以接收元组、字符串、其他序列类型、迭代器等生成列表
1.3 使用生成器推导式创建
从形式上看,生成器推导式与列表推导式类似,只是生成器推导式使用小括号。列表推导式直接生成列表对象,生成器推导式生成等不列表也不是元组,而是生成器对象。
- 我们可以通过生成器对象,转换成列表或者元组。
- 也可以使用生成器对象的next()方法进行遍历。
- 或者直接作为迭代对象来使用。
总之,不管什么方式使用,元素访问结束后,如果需要重新访问其中的元素,必须重新创建该生成器对象。
>>> t = (x*2 for x in range(6))
>>> t
<generator object <genexpr> at 0x10f4e8450>
>>> tuple(t) # 生成器第一访问
(0, 2, 4, 6, 8, 10)
>>> list(t) #只能访问一次,第二次就为空,需要再次生成一次
[]
>>> t
<generator object <genexpr> at 0x10f4e8450>
>>> list(t)
[]
>>> tuple(t)
()
生成器对象,使用next()来访问
>>> t.__next__()
0
>>> t.__next__()
2
>>> t.__next__()
4
>>> t.__next__()
6
>>> t.__next__()
8
>>> t.__next__()
10
>>> t.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
2.基本方法
2.1 元素访问
元组的元素是不能修改的。强制修改时,python解释器会报错。
>>> t = (1,9,6)
>>> t[0]=100
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>
我们可以通过索引来进行访问。
>>> t = (1,9,6)
>>> t[0]
1
>>> t[1]
9
>>> t[2]
6
>>> t[-3]
1
>>> t[-2]
9
>>> t[-1]
6
>>>
2.2 切片操作
我们使用索引来进行切片。
举个例子:定义一个元组 t = (1,9,6)
>>> t = (1,9,6)
>>> t[-3:-1]
(1, 9)
>>> t[0,2]
(1, 9)
倒序输出元组:
>>> t[::-1]
(6, 9, 1)
>>>
2.3 计数
- len()函数,可以对元组进行求长度
- max()函数,可以找到元组中最大的数
- min()函数,可以找到元组中最小的数
>>> t = (1,9,6)
>>> len(t)
3
>>> max(t)
9
>>> min(t)
1
>>>
3. 特殊操作
元组是不可变的,假设我们工作场景,需要对元组进行修改,删除操作,我们该如何操作呢?
3.1 修改元组
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合
>>> t = (1,9,6)
>>> t2 = (100,300)
>>> t3 = t+t2 # 创建新的对象t3
>>> t3
(1, 9, 6, 100, 300)
>>>
3.2 删除元组
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组
>>> t = (1,9,6)
>>> t
(1, 9, 6)
>>> del t
>>> t #以上实例元组被删除后,输出变量会有异常信息
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 't' is not defined
>>>
重点回顾:
- 元组的核心特点是:不可变序列
- 元组的访问和处理速度比列表快
- 与整数和字符串一样,元组可以作为字典的key,列表则永远不能作为字典的key来使用
好啦,以上是关于元组的学习。
欢迎大佬留言评论指正。
我是正在学习python的盆友圈的小可爱,下次见~