深入浅出 Python:列表(List)与元组(Tuple)
深入浅出 Python:列表(List)与元组(Tuple)
引言
Python 中的列表(List)和元组(Tuple)是两种非常常用的数据结构,它们都可以存储多个元素。虽然它们看起来相似,但在使用场景、性能和功能上存在显著差异。本文将深入浅出地介绍 Python 的列表和元组,帮助你理解它们的区别、应用场景以及如何高效地使用它们。
1. 列表(List)
1.1 列表的基本概念
列表是 Python 中一种有序、可变的数据结构,可以存储不同类型的元素。列表中的元素可以通过索引访问,索引从 0 开始。列表的特点是:
1.1.1 创建列表
创建列表有多种方式,最常见的是使用方括号 []
包裹元素,元素之间用逗号分隔。
# 创建一个空列表
empty_list = []
# 创建一个包含多个元素的列表
fruits = ["apple", "banana", "orange"]
# 使用 list() 函数创建列表
numbers = list(range(1, 6)) # [1, 2, 3, 4, 5]
1.2 列表的操作
1.2.1 访问元素
通过索引可以访问列表中的元素,索引从 0 开始。你还可以使用负索引从列表末尾开始访问元素。
fruits = ["apple", "banana", "orange"]
# 访问第一个元素
print(fruits[0]) # 输出: apple
# 访问最后一个元素
print(fruits[-1]) # 输出: orange
1.2.2 修改元素
由于列表是可变的,你可以直接通过索引修改列表中的元素。
fruits = ["apple", "banana", "orange"]
# 修改第二个元素
fruits[1] = "grape"
print(fruits) # 输出: ['apple', 'grape', 'orange']
1.2.3 添加元素
append()
:在列表末尾添加一个元素。insert()
:在指定位置插入一个元素。extend()
:将另一个列表的所有元素添加到当前列表的末尾。fruits = ["apple", "banana", "orange"]
# 在末尾添加一个元素
fruits.append("grape")
print(fruits) # 输出: ['apple', 'banana', 'orange', 'grape']
# 在指定位置插入一个元素
fruits.insert(1, "pear")
print(fruits) # 输出: ['apple', 'pear', 'banana', 'orange', 'grape']
# 将另一个列表的所有元素添加到当前列表
more_fruits = ["mango", "kiwi"]
fruits.extend(more_fruits)
print(fruits) # 输出: ['apple', 'pear', 'banana', 'orange', 'grape', 'mango', 'kiwi']
1.2.4 删除元素
remove()
:根据元素的值删除第一个匹配的元素。pop()
:删除并返回指定索引处的元素,默认删除最后一个元素。del
:根据索引或切片删除元素。fruits = ["apple", "banana", "orange", "grape"]
# 根据值删除元素
fruits.remove("banana")
print(fruits) # 输出: ['apple', 'orange', 'grape']
# 删除并返回最后一个元素
last_fruit = fruits.pop()
print(last_fruit) # 输出: grape
print(fruits) # 输出: ['apple', 'orange']
# 使用 del 删除指定索引的元素
del fruits[0]
print(fruits) # 输出: ['orange']
1.2.5 切片操作
切片操作可以从列表中提取子列表。切片的基本语法为 list[start:end:step]
,其中 start
是起始索引,end
是结束索引(不包括),step
是步长。
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 提取前三个元素
print(numbers[:3]) # 输出: [0, 1, 2]
# 提取从第四个元素到最后一个元素
print(numbers[3:]) # 输出: [3, 4, 5, 6, 7, 8, 9]
# 提取每隔两个元素
print(numbers[::2]) # 输出: [0, 2, 4, 6, 8]
# 反转列表
print(numbers[::-1]) # 输出: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
1.3 列表的常用方法
len()
:返回列表的长度。count()
:统计某个元素在列表中出现的次数。sort()
:对列表进行原地排序。reverse()
:反转列表中的元素。index()
:查找某个元素的索引位置。numbers = [1, 2, 3, 2, 4, 2]
# 获取列表的长度
print(len(numbers)) # 输出: 6
# 统计某个元素出现的次数
print(numbers.count(2)) # 输出: 3
# 对列表进行排序
numbers.sort()
print(numbers) # 输出: [1, 2, 2, 2, 3, 4]
# 反转列表
numbers.reverse()
print(numbers) # 输出: [4, 3, 2, 2, 2, 1]
# 查找元素的索引
print(numbers.index(3)) # 输出: 1
2. 元组(Tuple)
2.1 元组的基本概念
元组是 Python 中另一种有序的数据结构,类似于列表,但它是不可变的。这意味着一旦创建了元组,就不能修改、添加或删除其中的元素。元组的特点是:
2.1.1 创建元组
创建元组的方式与列表类似,使用圆括号 ()
包裹元素,元素之间用逗号分隔。如果元组只有一个元素,必须在元素后面加一个逗号。
# 创建一个空元组
empty_tuple = ()
# 创建一个包含多个元素的元组
colors = ("red", "green", "blue")
# 创建一个只有一个元素的元组
single_element_tuple = ("apple",)
# 使用 tuple() 函数创建元组
numbers = tuple([1, 2, 3, 4, 5])
2.2 元组的操作
2.2.1 访问元素
元组的访问方式与列表相同,可以通过索引访问元素,支持正索引和负索引。
colors = ("red", "green", "blue")
# 访问第一个元素
print(colors[0]) # 输出: red
# 访问最后一个元素
print(colors[-1]) # 输出: blue
2.2.2 不可变性
元组是不可变的,因此不能修改、添加或删除元素。如果你需要修改元组的内容,可以将其转换为列表,修改后再转换回元组。
colors = ("red", "green", "blue")
# 尝试修改元组会抛出错误
# colors[1] = "yellow" # TypeError: 'tuple' object does not support item assignment
# 将元组转换为列表进行修改
color_list = list(colors)
color_list[1] = "yellow"
colors = tuple(color_list)
print(colors) # 输出: ('red', 'yellow', 'blue')
2.2.3 切片操作
元组也支持切片操作,语法与列表相同。
numbers = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
# 提取前三个元素
print(numbers[:3]) # 输出: (0, 1, 2)
# 提取从第四个元素到最后一个元素
print(numbers[3:]) # 输出: (3, 4, 5, 6, 7, 8, 9)
# 提取每隔两个元素
print(numbers[::2]) # 输出: (0, 2, 4, 6, 8)
# 反转元组
print(numbers[::-1]) # 输出: (9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
2.3 元组的常用方法
len()
:返回元组的长度。count()
:统计某个元素在元组中出现的次数。index()
:查找某个元素的索引位置。numbers = (1, 2, 3, 2, 4, 2)
# 获取元组的长度
print(len(numbers)) # 输出: 6
# 统计某个元素出现的次数
print(numbers.count(2)) # 输出: 3
# 查找元素的索引
print(numbers.index(3)) # 输出: 2
3. 列表与元组的区别
特性 | 列表(List) | 元组(Tuple) |
---|---|---|
可变性 | 可变,可以修改、添加或删除元素 | 不可变,一旦创建无法修改 |
性能 | 较慢,因为每次修改都需要重新分配内存 | 较快,因为不需要重新分配内存 |
用途 | 适合需要频繁修改的场景 | 适合不需要修改的场景,如配置项 |
内存占用 | 较大,因为需要额外的空间来支持修改 | 较小,因为不需要额外的空间 |
线程安全 | 不是线程安全的 | 是线程安全的 |
使用场景 | 动态数据集合,如购物车、任务队列 | 静态数据集合,如日期、坐标 |
4. 实际应用案例
4.1 学生信息管理系统
假设你正在开发一个学生信息管理系统,需要存储学生的姓名、年龄和成绩。我们可以使用元组来表示每个学生的信息,因为这些信息在系统中通常是固定的,不会频繁修改。
4.1.1 示例
# 定义一个元组表示学生信息
student = ("Alice", 20, 85)
# 打印学生信息
print(f"姓名: {student[0]}, 年龄: {student[1]}, 成绩: {student[2]}")
4.2 购物车系统
假设你正在开发一个购物车系统,用户可以添加商品到购物车,并且可以随时修改购物车中的商品数量或删除商品。我们可以使用列表来实现购物车的功能,因为购物车中的商品可能会频繁变化。
4.2.1 示例
# 初始化一个空购物车
cart = []
# 添加商品到购物车
cart.append(("apple", 3))
cart.append(("banana", 5))
# 修改商品数量
cart[0] = ("apple", 4)
# 删除商品
cart.remove(("banana", 5))
# 打印购物车内容
for item in cart:
print(f"商品: {item[0]}, 数量: {item[1]}")
4.3 坐标点集合
假设你需要存储一组二维坐标点,用于绘制图形或计算几何问题。由于坐标点是固定的,不会发生变化,我们可以使用元组来表示每个坐标点,并将多个坐标点存储在一个列表中。
4.3.1 示例
# 定义一个包含多个坐标点的列表
points = [(0, 0), (1, 1), (2, 2), (3, 3)]
# 计算所有点的平均值
x_sum = sum(point[0] for point in points)
y_sum = sum(point[1] for point in points)
average_x = x_sum / len(points)
average_y = y_sum / len(points)
print(f"所有点的平均坐标是: ({average_x}, {average_y})")
5. 总结
通过本文的学习,你已经掌握了 Python 中列表和元组的基本概念、操作方法以及它们之间的区别。列表是可变的,适用于需要频繁修改的场景;而元组是不可变的,适用于不需要修改的静态数据。选择合适的数据结构可以提高代码的效率和可维护性。
参考资料
作者:软件架构师笔记