Python快速学习——第4章:元组

5 阅读5分钟

第四章:元组

4.1 什么是元组?

元组就像 一个上了锁的集装箱,一旦创建,就不能再修改里面的内容。它和列表很像,但最大的区别是:元组是不可变的。元组用小括号()创建。

# 创建元组。
coordinates = (10, 20);
​
colors = ("红色", "绿色", "蓝色");
​
single_item = (42,);  # 注意:单个元素的元组需要加逗号。

4.2 元组的创建方式

元组可以用多种方式创建:

# 直接使用圆括号创建
point = (3, 4)
​
# 可以省略圆括号(逗号分隔的多个值会自动组成元组)
dimensions = 100, 200
print(type(dimensions))  # <class 'tuple'># 使用tuple()函数从其他序列创建
numbers = tuple([1, 2, 3, 4, 5])  # (1, 2, 3, 4, 5)
chars = tuple("hello")             # ('h', 'e', 'l', 'l', 'o')# 创建空元组
empty_tuple = (); # 方法1。
empty_tuple2 = tuple(); # 方法2。

4.3 元组的基本操作

4.3.1 访问元组元素

元组支持索引和切片,就像列表一样:

colors = ("红色", "绿色", "蓝色", "黄色", "紫色");

print(colors[0]);    # 红色 - 第一个元素
print(colors[-1]);   # 紫色 - 最后一个元素
print(colors[1:4]);  # ('绿色', '蓝色', '黄色') - 切片操作。

4.3.2 元组长度

使用 len() 函数获取元组长度:

colors = ("红色", "绿色", "蓝色")
print(len(colors))  # 3

4.3.3 检查元素是否存在

使用 in 关键字检查元素是否在元组中:

colors = ("红色", "绿色", "蓝色")
print("红色" in colors)  # True
print("黑色" in colors)  # False

4.3.4 元组的不可变性

元组一旦创建就不能修改,这是它与列表最大的区别:

colors = ("红色", "绿色", "蓝色")

# 以下操作都会报错!
# colors[0] = "黑色"        # 不能修改元素
# colors.append("黄色")     # 不能添加元素
# colors.remove("红色")     # 不能删除元素

4.4 元组的常用方法

由于元组是不可变的,它的方法比列表少很多:

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

# count() - 统计元素出现的次数
print(numbers.count(2))  # 3

# index() - 返回元素的索引位置
print(numbers.index(3))  # 2
print(numbers.index(2, 2))  # 3 - 从索引2开始查找

4.5 元组的遍历

遍历元组的方式与列表相同:

colors = ("红色", "绿色", "蓝色")

# 直接遍历元素
for color in colors:
    print(f"颜色:{color}")

# 遍历索引和元素
for i, color in enumerate(colors):
    print(f"第{i}个颜色是:{color}")

4.6 元组的解包

元组解包是Python中一个很有用的特性:

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

# 解包时使用*收集剩余元素。
numbers = (1, 2, 3, 4, 5);
first, *middle, last = numbers;
print(first);   # 1。
print(middle);  # [2, 3, 4]。
print(last);    # 5。

# 交换变量的值(实际上使用了元组解包)
a, b = 10, 20
a, b = b, a
print(f"a={a}, b={b}")  # a=20, b=10

4.7 元组与列表的比较

特性列表元组
可变性可变不可变
语法方括号 []圆括号 ()
性能较慢较快
安全性较低较高
内存占用较大较小
用途存储可能变化的数据存储不应变化的数据

4.8 元组的应用场景

4.8.1 函数返回多个值

def calculate_stats(numbers):
    """计算数字列表的统计信息"""
    total = sum(numbers)
    count = len(numbers)
    average = total / count
    return total, count, average  # 返回一个元组

result = calculate_stats([1, 2, 3, 4, 5])
print(result)  # (15, 5, 3.0)

# 解包返回值
total, count, average = calculate_stats([1, 2, 3, 4, 5])
print(f"总和:{total}, 数量:{count}, 平均值:{average}")

4.8.2 作为字典的键

由于元组是不可变的,它可以作为字典的键,而列表不行:

# 元组可以作为字典的键。
coordinates_map = {
    (0, 0): "原点",
    (1, 0): "X轴上",
    (0, 1): "Y轴上"
};
print(coordinates_map[(0, 0)]);  # 原点。

# 列表不能作为字典的键(会报错)。
# invalid_dict = {[1, 2]: "值"}。

4.8.3 存储不应修改的数据

# 颜色常量
COLORS = ("红色", "绿色", "蓝色")

# 月份名称
MONTHS = ("一月", "二月", "三月", "四月", "五月", "六月",
          "七月", "八月", "九月", "十月", "十一月", "十二月")

# 配置信息
DATABASE_CONFIG = ("localhost", 3306, "my_database", "username", "password")

4.9 元组与列表的转换

元组和列表可以相互转换:

# 列表转元组
fruits_list = ["苹果", "香蕉", "橙子"]
fruits_tuple = tuple(fruits_list)
print(fruits_tuple)  # ('苹果', '香蕉', '橙子')

# 元组转列表
colors_tuple = ("红色", "绿色", "蓝色")
colors_list = list(colors_tuple)
print(colors_list)  # ['红色', '绿色', '蓝色']

4.10 命名元组

collections 模块中的 namedtuple 可以创建带有字段名的元组:

from collections import namedtuple

# 创建一个命名元组类型
Point = namedtuple("Point", ["x", "y"])

# 创建命名元组实例
p1 = Point(10, 20)
p2 = Point(x=30, y=40)

print(p1.x, p1.y)  # 10 20
print(p2.x, p2.y)  # 30 40

# 仍然支持普通的元组操作
print(p1[0], p1[1])  # 10 20

4.11 元组的性能优势

由于元组是不可变的,它在某些情况下比列表更高效:

import sys
import time
​
# 内存占用比较
numbers_list = [1, 2, 3, 4, 5]
numbers_tuple = (1, 2, 3, 4, 5)
​
print(f"列表占用内存: {sys.getsizeof(numbers_list)} 字节")
print(f"元组占用内存: {sys.getsizeof(numbers_tuple)} 字节")
​
# 创建速度比较(通常元组稍快)
start_time = time.time()
for _ in range(1000000):
    [1, 2, 3, 4, 5]
list_time = time.time() - start_time
​
start_time = time.time()
for _ in range(1000000):
    (1, 2, 3, 4, 5)
tuple_time = time.time() - start_time
​
print(f"列表创建时间: {list_time:.6f} 秒")
print(f"元组创建时间: {tuple_time:.6f} 秒")

本章笔记:

  • 元组是不可变的序列,一旦创建就不能修改。
  • 元组使用圆括号创建,但也可以省略圆括号。
  • 支持索引、切片、长度检查等基本操作。
  • 元组的方法很少,主要是count()和index()。
  • 元组解包是一个有用的特性,可以方便地提取元组中的值。
  • 元组比列表更安全、更高效,适合存储不应修改的数据。
  • 元组可以作为字典的键,而列表不行。
  • 函数可以使用元组返回多个值。
  • 命名元组提供了更友好的字段访问方式。
  • 元组和列表可以相互转换。