tuple(元组)
元组和列表类似,与列表的区别是列表是可变的【元素的值可以更改,长度可以发生变化】,
元组是不可变的
元组的数据标记是
()
【提高表达式优先级也是使用()
包含的】有些场景下存储的数据是固定的,像这种情况建议使用元组。【从内存角度来说 使用元组会比列表少占内存】
1. 元组的定义
元组有几个元素就称为几元组
- 使用
()
字面量形式来定义- 使用
tuple()
来构造
# 1. 元组的定义
t = () # 空元组
print(t, type(t)) # () <class 'tuple'>
# 当元组中只有一个数据时 元素后面必须加上逗号 【不加的话 解释器把它解释成提高表达式优先级的意思了】
t1 = (10)
print(type(t1), t1) # <class 'int'> 10
t2 = (10,) # 定义一元组的注意事项
print(type(t2), t2) # <class 'tuple'> (10,)
t3 = (12, 34, 56, 78)
print(t3)
# 用tuple构造 【把其他序列转换为元组类型】
t0 = tuple() # 空元组
print(t0) # ()
t1 = tuple('hello')
print(t1) # ('h', 'e', 'l', 'l', 'o')('h', 'e', 'l', 'l', 'o')
2. 元组的运算
"""
+ 合并 放在一个新的元组中
* 重复
+= 在当前元组的数据的基础上 合并新的序列 但是生成一个新的元组
*= 在当前元组的数据的基础上 完成重复 但是生成一个新的元组
比较运算符 > >= < <= == !=相同索引位置的元素进行比较 直到结果的出现
成员运算符 in 和 not in
身份运算符 id 、is 和 not is
"""
t1 = (1, 2, 3)
t2 = (5, 6, 7)
print(id(t1)) # 2245004633920
new_t = t1 + t2
print(new_t, t1, t2)
t1 += (8, 9)
print(t1, id(t1)) # (1, 2, 3, 8, 9) 2245045930640
t2 = (10,20) * 3
print(t2)
3. 索引和切片
元组的索引和切片操作更类同于字符串,因为是不可变的 只有获取没有修改
索引
Python对于序列的索引有两种方式的操作:
正向索引 【从左向右数】范围是[0, 长度N-1]
负向索引 【从右向左数】范围是[-1, -N, -1] — 递减数列
对于有序序列来说,想要定位获取或者修改序列中的元素,就需要索引来进行定位,格式:
序列[索引]
切片
通过索引定位范围区域,在这个区域中提取相关的子串信息,切片的操作是
序列[起始索引:结束索引:步长]
起始索引和结束索引只是定位范围的,使用正向索引和负向索引均可
根据步长的正负情况切片是分为两种的
正向切片 【从左向右提取子串】
步长是为正数,起始索引定位的字符应该在结束索引定位的左边
从起始索引定位的字符开始 按照步长 获取相应的字符,注意不包含结束索引对应的位置
负向切片 【从右向左提取子串】
步长是负数,起始索引定位的字符应该在结束索引定位的右边
从起始索引定位的字符开始 按照步长 获取相应的字符,注意不包含结束索引对应的位置
切片的操作中有些内容是可以省略的:
:步长
可以省略,表示步长为1起始索引
可以省略,如果是正向切片 表示从最左边开始, 如果是负向切片 表示从最右边开始结束索引
可以省略,如果是正向切片 表示到最右边结束,如果是负向切片 表示到最左边结束
t = (13, 45, 67, 8, 29, 33, 56, 71)
# 获取倒数第3个元素
print(t[-3])
# 获取前3个
print(t[:3]) # (13, 45, 67)
# 反转
print(t[::-1])
4. 元组的遍历
方式1:直接遍历获取元素
for 变量名 in 元组: 操作
方式2:使用range生成下标数列,根据下标获取元素
for 变量名 in range(len(元组)): 操作
方式3:enumerate枚举遍历序列
对序列操作完成时候 会生成一个新的序列,这个序列中的元素是一个二元组
(下标, 元素)
# 遍历
for ele in t:
print(ele)
for i in range(len(t)):
print(t[i])
for i, ele in enumerate(t):
print(i, ele)
5. 元组的操作
t = (28, 34, 56, 78, 19, 23, 45, 67, 19)
print(len(t)) # 元组的长度
print(t.index(19)) # 获取元素第一次出现的位置
print(t.index(19, 5)) # 从下标5开始第一次出现的位置
# 在区间[5,8)之间第一次出现的位置
# print(t.index(19, 5, 8)) # ValueError: tuple.index(x): x not in tuple
# 统计某个元素出现的次数
print(t.count(19)) # 2
6. 打包和解包
打包:当我们使用逗号分割定义多个数据,赋值给一个变量时, 会将数据打包成元组,赋值给该变量
解包:把序列中的元素赋值给多个变量时,把序列解包,将相同位置的数据赋值给对应位置的变量
# 打包
a = 10, 22, 33, 45, 61
print(type(a), a) # <class 'tuple'> (10, 22, 33, 45, 61)
# 解包
a, b, c = 'xyz'
print(a, b, c) # 'x' 'y' 'z'
m, n = [11, 27]
print(m, n) # 11 27
p, q, k = range(3)
print(p, q, k) # 0 1 2
需要注意:
当变量的个数与序列中元素个数不对等时,会出现问题报错的
# h, i, j = [19, 22] # ValueError: not enough values to unpack (expected 3, got 2) # h, i, j, l, e = [19, 22, 33, 56, 71, 89] # ValueError: too many values to unpack (expected 5) # h, i, j, l, e, *t = [19, 22, 33, 56, 71, 89, 78, 65] # print(h, i,j, l, e, t ) # 19 22 33 56 71 [89, 78, 65] # *t, h, i, j, l, e = [19, 22, 33, 56, 71, 89, 78, 65] # print(h, i,j, l, e, t ) # 56 71 89 78 65 [19, 22, 33] h, i, *t, j, l, e = [19, 22, 33, 56, 71, 89, 78, 65] print(h, i,j, l, e, t ) # 19 22 89 78 65 [33, 56, 71]
这个错误可以使用星号表达式来解决 , 用
*
修饰一个变量名,用它去接受过多的数据,因为*
修饰完成之后将其变量容器型数据,可以来接受多个数据总结:
元组:可以容纳多个数据、可以容纳不同类型的数据(混装)、数据是有序存储的(下标索引)、允许重复数据存在、不可以修改(增加或删除元素等)、支持for循环、多数特性和list一致,不同点在于不可修改的特性。