元组(tuple)是 Python 中有序、不可变的序列类型。外观与列表相似,支持下标与切片,但创建后不能替换其中的元素。本节说明字面量与单元素写法、不可变性的含义、解包与遍历,并对照列表讨论选型。不可变记录、多返回值与可作字典键等场景常用元组。
先建一个元组
常见写法为圆括号与逗号分隔的元素。下列元组含三个整数,可通过下标访问,也可用 len 求长度:
t = (1, 2, 3)
print(t) # (1, 2, 3)
print(t[0]) # 1
print(len(t)) # 3元素类型可以混合。空元组写作 ()。仅含一个元素时逗号不可省略:表达式中的 (5) 仍为整数 5,须写作 (5,) 才被识别为元组。赋值时外层圆括号也可省略,逗号才是构成元组的关键:
a = ()
b = (5,)
c = (1, "hello", 3.5)
d = 1, 2, 3
print(b, d) # (5,) (1, 2, 3)不可变意味着什么
对某下标重新赋值,或调用列表专有的 append,将分别触发 TypeError 与 AttributeError:
t = (1, 2, 3)
# t[0] = 99 # TypeError
# t.append(4) # AttributeError若需调整内容,通常先 list(t) 转为列表,修改后再 tuple(...) 得到新元组,原对象未被原地改写。
不可变约束的是元组各槽位的引用,而非槽位内可变对象的内容:若某位置存放列表,仍可向该列表追加元素,元组长度与各位置引用不变。若要求整份数据不可变,应避免在元组中嵌入列表等可变对象。
下标与切片
正下标从 0 起算,负下标从右端计数,-1 为最后一项。切片区间为含头不含尾,步长为负时可得到逆序的新元组:
t = (10, 20, 30, 40, 50)
print(t[0]) # 10
print(t[-1]) # 50
print(t[1:4]) # (20, 30, 40)
print(t[::-1]) # (50, 40, 30, 20, 10)切片结果仍为元组。元组不支持对切片区间赋值,这一点与列表不同。
元组解包
左侧多个目标与右侧一个元组按位置对应,称为解包。交换两个变量时,右侧先构成临时元组再解包至左侧。函数中 return a, b 实际返回元组,调用方可同样解包接收:
point = (3, 5)
x, y = point
print(x, y) # 3 5
a, b = b, a
print(a, b)
def get_point():
return 3, 5
x, y = get_point()
print(x, y) # 3 5左右两侧元素个数须一致,否则抛出 ValueError。元素较多时可用 * 收集剩余部分,例如 first, *mid, last = t。
遍历与成员判断
for 可遍历元组中每一项。in 用于成员检测,count 与 index 的用法与列表中的同名方法相近:
t = ("a", "b", "c")
for item in t:
print(item, end=" ") # a b c
print()
print("b" in t) # True
print(t.count("a")) # 1
print(t.index("c")) # 2元组和列表怎么选
| 特点 | 列表 list | 元组 tuple |
|---|---|---|
| 可变性 | 可变 | 不可变 |
| 语法 | 中括号 [] | 小括号 () 或省略 |
| 用途 | 数据还会增删改 | 当作固定记录 |
| 性能与键 | 稍慢 | 稍快,且可作字典键 |
若后续仍需增删元素,宜使用列表。若逻辑上为固定记录,或需要作为字典键,宜使用元组。元组可哈希而列表不可哈希,这是能否作为键的根本原因。
常见误区
- 单元素元组若省略逗号,
(5)仍为整数而非元组。 - 需要修改内容时,应经列表中转而非对下标赋值。
- 元组内嵌可变对象时,内部对象仍可被修改,不可变仅约束元组自身结构。
本节说明了 Python 元组的创建、不可变性、解包及与列表的对比。下一篇介绍集合:元素唯一、无序及集合运算。