【Python入门】第5篇:数据结构初探(列表、元组、字典、集合)
在前几篇文章中,我们学习了变量可以存储单个数据,如一个数字、一个字符串。但在现实世界中,数据往往是以群体的形式出现:一份学生名单、一系列商品价格、一个人的多种属性(姓名、年龄、身高)等。
为了高效地组织和管理这些相关的数据集合,Python提供了几种强大的"集装箱"——数据结构。我们将重点学习其中最常用的四种:列表、元组、字典和集合。
一、列表(List):有序可变的集合
列表是Python中最灵活、最常用的数据结构,用于存储一系列有序的、可修改的元素。
1.1 创建列表
使用方括号 []创建,元素之间用逗号分隔。列表可以包含不同类型的元素。
# 创建一个水果列表
fruits = ["苹果", "香蕉", "橙子", "葡萄"]# 包含不同类型元素的列表
mixed_list = [1, "hello", 3.14, True]# 空列表
empty_list = []
1.2 访问列表元素:索引和切片
列表中的每个元素都有其位置编号,称为索引,从0开始。
fruits = ["苹果", "香蕉", "橙子", "葡萄"]# 通过索引访问单个元素
print(fruits[0]) # 输出:苹果(第一个元素)
print(fruits[2]) # 输出:橙子(第三个元素)
print(fruits[-1]) # 输出:葡萄(最后一个元素,-1表示倒数第一)# 切片:获取子列表 [起始索引:结束索引:步长]
print(fruits[1:3]) # 输出:['香蕉', '橙子'](索引1到3,不包括3)
print(fruits[:2]) # 输出:['苹果', '香蕉'](从开始到索引2)
print(fruits[::2]) # 输出:['苹果', '橙子'](每隔一个元素取一个)
1.3 修改列表:增删改查
列表是可变的,可以修改其内容。
fruits = ["苹果", "香蕉", "橙子"]# 改:修改指定位置的元素
fruits[1] = "芒果"
print(fruits) # 输出:['苹果', '芒果', '橙子']# 增:在末尾添加元素
fruits.append("草莓")
print(fruits) # 输出:['苹果', '芒果', '橙子', '草莓']# 增:在指定位置插入元素
fruits.insert(1, "菠萝")
print(fruits) # 输出:['苹果', '菠萝', '芒果', '橙子', '草莓']# 删:按值删除元素
fruits.remove("芒果")
print(fruits) # 输出:['苹果', '菠萝', '橙子', '草莓']# 删:按索引删除元素
del fruits[0]
print(fruits) # 输出:['菠萝', '橙子', '草莓']
1.4 列表与循环的完美结合
fruits = ["苹果", "香蕉", "橙子"]# 遍历列表
for fruit in fruits:print("我喜欢吃", fruit)# 带索引的遍历
for index, fruit in enumerate(fruits):print(f"第{index+1}个水果是:{fruit}")
二、元组(Tuple):有序不可变的集合
元组与列表类似,也是有序的元素集合,但有一个关键区别:元组是不可变的,创建后不能修改。
2.1 创建元组
使用圆括号 ()创建,或者直接用逗号分隔。
# 创建元组
colors = ("红色", "绿色", "蓝色")
point = (10, 20)# 单个元素的元组(注意末尾的逗号)
single_tuple = (5,)# 空元组
empty_tuple = ()
2.2 元组的特性
rgb = ("红色", "绿色", "蓝色")# 可以访问,但不能修改
print(rgb[0]) # 输出:红色
# rgb[0] = "黄色" # 这行会报错!元组不可修改# 元组拆包(很实用的特性)
r, g, b = rgb
print(r, g, b) # 输出:红色 绿色 蓝色
2.3 何时使用元组?
- 当希望数据不被意外修改时(如常量、配置信息)
- 作为字典的键(因为不可变)
- 函数返回多个值时(实际上返回的是一个元组)
三、字典(Dictionary):键值对的映射
字典用于存储**键值对(key-value pairs)**的映射关系,通过键(key)来快速查找对应的值(value)。
3.1 创建字典
使用花括号 {},键值对用冒号 :分隔。
# 创建学生信息的字典
student = {"name": "张三","age": 20,"major": "计算机科学","grades": [85, 92, 78]
}# 空字典
empty_dict = {}
3.2 访问和修改字典
student = {"name": "张三", "age": 20}# 通过键访问值
print(student["name"]) # 输出:张三
print(student.get("age")) # 输出:20# 安全的访问方式,如果键不存在返回默认值
print(student.get("height", "未知")) # 输出:未知# 添加或修改键值对
student["height"] = 175 # 添加新键值对
student["age"] = 21 # 修改已有键的值# 删除键值对
del student["age"]
3.3 字典的遍历
student = {"name": "张三", "age": 20, "major": "计算机科学"}# 遍历所有键
for key in student:print(key, ":", student[key])# 更高效的方式
for key, value in student.items():print(f"{key}: {value}")
四、集合(Set):无序不重复的元素集
集合是一个无序的、不重复元素的集合,主要用于成员关系测试和消除重复元素。
4.1 创建集合
使用花括号 {}或 set()函数。
# 创建集合
fruits_set = {"苹果", "香蕉", "橙子", "苹果"} # 重复的"苹果"会被自动去除
numbers = set([1, 2, 3, 2, 1]) # 从列表创建集合,去重print(fruits_set) # 输出:{'橙子', '香蕉', '苹果'}(顺序可能不同)
print(numbers) # 输出:{1, 2, 3}
4.2 集合操作
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}# 并集
print(A | B) # 输出:{1, 2, 3, 4, 5, 6, 7, 8}
print(A.union(B))# 交集
print(A & B) # 输出:{4, 5}
print(A.intersection(B))# 差集(在A中但不在B中)
print(A - B) # 输出:{1, 2, 3}
print(A.difference(B))# 添加元素
A.add(6)
五、四种数据结构对比
类型 | 是否有序 | 是否可变 | 元素是否可重复 | 主要用途 |
---|---|---|---|---|
列表(List) | 有序 | 可变 | 是 | 存储有序序列,可增删改 |
元组(Tuple) | 有序 | 不可变 | 是 | 存储不应修改的数据 |
字典(Dict) | 无序(Python3.7+有序) | 可变 | 键不可重复 | 键值对映射,快速查找 |
集合(Set) | 无序 | 可变 | 否 | 去重,集合运算 |
六、综合实践:学生成绩管理系统
让我们用学到的数据结构构建一个简单的系统:
# 使用列表存储多个学生(每个学生用字典表示)
students = [{"name": "张三", "chinese": 85, "math": 92, "english": 78},{"name": "李四", "chinese": 92, "math": 88, "english": 95},{"name": "王五", "chinese": 78, "math": 85, "english": 82}
]# 计算每个学生的平均分并添加到字典中
for student in students:scores = [student["chinese"], student["math"], student["english"]]student["average"] = sum(scores) / len(scores)# 找出所有科目,用于后续统计
subjects = {"chinese", "math", "english"} # 使用集合# 打印每个学生的信息
print("学生成绩单:")
print("-" * 40)
for student in students:print(f"姓名:{student['name']}")for subject in subjects:print(f" {subject}:{student[subject]}")print(f" 平均分:{student['average']:.2f}")print("-" * 20)# 计算全班各科平均分
class_avg = {}
for subject in subjects:total = sum(student[subject] for student in students)class_avg[subject] = total / len(students)print("全班各科平均分:")
for subject, avg in class_avg.items():print(f"{subject}:{avg:.2f}")