Skip to content

元组(Tuples)

不可变的列表 —— 用于存储固定数据


什么是元组?

元组(Tuple)是 Python 中的不可变序列,类似于列表,但创建后不能修改

列表 vs 元组

特性列表(List)元组(Tuple)
语法[1, 2, 3](1, 2, 3)
可变性可修改不可修改
速度较慢较快
用途动态数据固定数据

什么时候用元组?

  • 数据不应被修改(如坐标、日期)
  • 作为字典的键(列表不行)
  • 函数返回多个值

创建元组

1. 基本创建

python
# 空元组
empty_tuple = ()

# 单个元素(注意逗号!)
single = (5,)  #  这是元组
not_tuple = (5)  #  这只是数字 5

# 多个元素
coordinates = (10, 20)
student_info = ("Alice", 25, "Economics")

# 不用括号也行(但不推荐)
point = 10, 20
print(type(point))  # <class 'tuple'>

2. 从列表转换

python
ages_list = [25, 30, 35]
ages_tuple = tuple(ages_list)
print(ages_tuple)  # (25, 30, 35)

访问元组元素

索引和切片(与列表相同)

python
student = ("Alice", 25, "Economics", 3.85)

# 索引访问
print(student[0])   # Alice
print(student[-1])  # 3.85

# 切片
print(student[1:3])  # (25, 'Economics')
print(student[:2])   # ('Alice', 25)

元组解包(Unpacking)

python
# 基本解包
point = (10, 20)
x, y = point
print(f"x={x}, y={y}")  # x=10, y=20

# 多变量解包
student = ("Alice", 25, "Economics")
name, age, major = student
print(name, age, major)  # Alice 25 Economics

# 部分解包(使用 *)
scores = (85, 90, 78, 92, 88)
first, second, *rest = scores
print(first)   # 85
print(second)  # 90
print(rest)    # [78, 92, 88](注意:rest 是列表!)

社科应用

python
# 调查数据:(ID, 性别, 年龄, 收入)
respondent = (1001, "Female", 30, 75000)

# 解包
resp_id, gender, age, income = respondent
print(f"受访者 {resp_id}: {gender}, {age}岁, 收入${income:,}")

元组的不可变性

python
student = ("Alice", 25, "Economics")

#  不能修改
student[1] = 26  # TypeError: 'tuple' object does not support item assignment

#  不能添加
student.append("GPA")  # AttributeError: 'tuple' object has no attribute 'append'

#  不能删除
del student[0]  # TypeError

#  可以整个替换
student = ("Bob", 28, "Sociology")

为什么需要不可变?

  • 防止意外修改重要数据
  • 可以作为字典的键
  • 更快的性能

元组操作

1. 基本操作

python
numbers = (1, 2, 3, 4, 5, 2, 3)

# 长度
print(len(numbers))  # 7

# 最大/最小/求和
print(max(numbers))  # 5
print(min(numbers))  # 1
print(sum(numbers))  # 20

# 计数
print(numbers.count(2))  # 2

# 查找索引
print(numbers.index(3))  # 2(第一次出现的位置)

# 检查存在
print(2 in numbers)  # True

2. 连接和重复

python
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)

# 连接
combined = tuple1 + tuple2
print(combined)  # (1, 2, 3, 4, 5, 6)

# 重复
repeated = tuple1 * 3
print(repeated)  # (1, 2, 3, 1, 2, 3, 1, 2, 3)

实战案例

案例 1:地理坐标

python
# 城市坐标(经度,纬度)
cities = {
    "Beijing": (39.9042, 116.4074),
    "Shanghai": (31.2304, 121.4737),
    "Guangzhou": (23.1291, 113.2644)
}

# 计算北京和上海的距离(简化版)
import math

def calculate_distance(coord1, coord2):
    lat1, lon1 = coord1
    lat2, lon2 = coord2

    # 简化的距离计算
    distance = math.sqrt((lat2 - lat1)**2 + (lon2 - lon1)**2)
    return distance * 111  # 转换为公里(粗略)

beijing = cities["Beijing"]
shanghai = cities["Shanghai"]
dist = calculate_distance(beijing, shanghai)
print(f"北京到上海距离约: {dist:.0f} 公里")

案例 2:问卷元数据

python
# 问卷基本信息(不应被修改)
survey_metadata = (
    "中国居民收入调查",  # 问卷名称
    "2024-01-01",        # 开始日期
    "2024-12-31",        # 结束日期
    1000,                 # 目标样本量
    "中文"                # 语言
)

# 解包
name, start_date, end_date, target_n, language = survey_metadata

print(f"=== 问卷信息 ===")
print(f"名称: {name}")
print(f"周期: {start_date}{end_date}")
print(f"目标样本: {target_n}")
print(f"语言: {language}")

案例 3:函数返回多值

python
def calculate_statistics(data):
    """计算描述性统计,返回元组"""
    n = len(data)
    mean = sum(data) / n
    sorted_data = sorted(data)
    median = sorted_data[n//2]
    minimum = min(data)
    maximum = max(data)

    return (n, mean, median, minimum, maximum)

# 使用
scores = [85, 92, 78, 90, 88, 76, 95, 82]
n, mean, median, min_val, max_val = calculate_statistics(scores)

print(f"样本量: {n}")
print(f"平均数: {mean:.2f}")
print(f"中位数: {median}")
print(f"最小值: {min_val}")
print(f"最大值: {max_val}")

元组与列表的转换

python
# 列表转元组
ages_list = [25, 30, 35, 40]
ages_tuple = tuple(ages_list)
print(ages_tuple)  # (25, 30, 35, 40)

# 元组转列表
ages_tuple = (25, 30, 35, 40)
ages_list = list(ages_tuple)
print(ages_list)  # [25, 30, 35, 40]

实用场景:需要修改元组时

python
# 原始元组
student = ("Alice", 25, "Economics")

# 转为列表修改
student_list = list(student)
student_list[1] = 26  # 修改年龄
student = tuple(student_list)  # 转回元组

print(student)  # ('Alice', 26, 'Economics')

高级应用:命名元组(namedtuple)

普通元组的问题:只能用索引访问,不够直观。

python
from collections import namedtuple

# 定义命名元组
Student = namedtuple('Student', ['name', 'age', 'major', 'gpa'])

# 创建实例
alice = Student(name="Alice", age=25, major="Economics", gpa=3.85)

# 访问(两种方式)
print(alice.name)   # Alice(更直观)
print(alice[0])     # Alice(也可以用索引)

print(alice.gpa)    # 3.85
print(alice[-1])    # 3.85

# 仍然是元组,不可修改
# alice.age = 26  #  AttributeError

社科应用

python
from collections import namedtuple

# 定义调查响应结构
Response = namedtuple('Response', [
    'respondent_id',
    'age',
    'gender',
    'income',
    'education',
    'satisfaction'
])

# 创建响应
resp1 = Response(
    respondent_id=1001,
    age=30,
    gender="Female",
    income=75000,
    education="Bachelor's",
    satisfaction=4
)

# 直观访问
print(f"受访者 {resp1.respondent_id}:")
print(f"  年龄: {resp1.age}")
print(f"  收入: ${resp1.income:,}")
print(f"  满意度: {resp1.satisfaction}/5")

何时用列表 vs 元组?

场景使用列表使用元组
收集受访者年龄ages = [25, 30, ...]
地理坐标point = (39.9, 116.4)
问卷元数据metadata = ("调查", "2024")
动态添加数据data.append(x)
函数返回多值return (mean, std, n)
作为字典键{(x, y): value}

经验法则

  • 数据会变 → 用列表
  • 数据不变 → 用元组

常见错误

错误 1:忘记单元素元组的逗号

python
#  不是元组
single = (5)
print(type(single))  # <class 'int'>

#  是元组
single = (5,)
print(type(single))  # <class 'tuple'>

错误 2:尝试修改元组

python
coords = (10, 20)
coords[0] = 15  #  TypeError: 'tuple' object does not support item assignment

错误 3:元组与列表混淆

python
# 元组没有 append 方法
numbers = (1, 2, 3)
numbers.append(4)  #  AttributeError

# 应该用列表
numbers = [1, 2, 3]
numbers.append(4)  #

练习题

练习 1:RGB 颜色

python
# 定义几个颜色(RGB元组)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)

# 任务:
# 1. 创建一个函数,接受 RGB 元组,返回颜色名称
# 2. 计算红色和绿色的"距离"(欧氏距离)

练习 2:学生记录

python
# 使用命名元组创建学生记录系统
# 字段: id, name, age, major, gpa
# 创建3个学生,计算平均GPA

练习 3:函数返回多值

python
# 编写函数计算收入的四分位数
incomes = [45000, 50000, 60000, 75000, 80000, 95000, 120000, 150000]

# 函数返回 (Q1, Q2, Q3) 作为元组
# 提示:排序后取 25%, 50%, 75% 位置

下一步

在下一节中,我们将学习 字典(Dictionaries),Python 最强大的数据结构之一,类似于 R 的 named list。

继续前进!

基于 MIT 许可证发布。内容版权归作者所有。