第二单元:数据结构
掌握Python核心数据结构,构建高效程序
预计学习时间:4-5小时
单元介绍
欢迎来到Python基础课程的第二单元!在这个单元中,你将学习Python中最重要的数据结构,这些是构建复杂程序的基础。
学习目标
- 掌握列表的高级操作
- 理解元组的特性和使用场景
- 学会使用字典存储键值对数据
- 掌握集合的特性和操作
- 学习数据结构的高级操作和最佳实践
- 能够根据不同场景选择合适的数据结构
学习提示
💡 重要提示:数据结构是编程的基础,理解它们的特性和使用场景将帮助你写出更高效、更清晰的代码。建议你多做练习,加深对这些数据结构的理解!
2.1 列表进阶:更强大的列表操作
在第一单元中,我们已经学习了列表的基础知识。现在让我们深入了解列表的高级操作!
列表推导式
列表推导式是Python中创建列表的一种简洁方式:
# 传统方式创建列表
numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
squares.append(num * num)
print(squares)
# 使用列表推导式
numbers = [1, 2, 3, 4, 5]
squares = [num * num for num in numbers]
print(squares)
# 带条件的列表推导式
even_squares = [num * num for num in numbers if num % 2 == 0]
print(even_squares)
# 嵌套列表推导式
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)
列表的高级方法
fruits = ["apple", "banana", "cherry", "date"]
# 排序
fruits.sort()
print("排序后:", fruits)
# 反转
fruits.reverse()
print("反转后:", fruits)
# 复制列表
fruits_copy = fruits.copy()
print("副本:", fruits_copy)
# 清空列表
fruits_copy.clear()
print("清空后:", fruits_copy)
# 扩展列表
more_fruits = ["elderberry", "fig"]
fruits.extend(more_fruits)
print("扩展后:", fruits)
# 查找元素索引
print("banana的索引:", fruits.index("banana"))
# 统计元素出现次数
fruits.append("banana")
print("banana出现次数:", fruits.count("banana"))
列表的切片操作
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 基本切片
print("前5个元素:", numbers[0:5])
print("从索引2开始:", numbers[2:])
print("到索引7结束:", numbers[:7])
# 步长切片
print("每隔一个元素:", numbers[::2])
print("从1开始每隔2个元素:", numbers[1::2])
# 负数索引和切片
print("最后3个元素:", numbers[-3:])
print("反转列表:", numbers[::-1])
# 修改切片
numbers[2:5] = [20, 30, 40]
print("修改后:", numbers)
# 插入元素
numbers[5:5] = [45, 50]
print("插入后:", numbers)
# 删除元素
numbers[2:5] = []
print("删除后:", numbers)
2.2 元组:不可变的序列
元组是一种不可变的序列类型,与列表类似,但一旦创建就不能修改。
创建元组
# 使用圆括号创建元组
t1 = (1, 2, 3)
print(t1)
# 不使用括号创建元组
t2 = 4, 5, 6
print(t2)
# 创建单元素元组(必须加逗号)
t3 = (7,)
print(t3)
# 使用tuple()函数创建元组
t4 = tuple([1, 2, 3])
print(t4)
t5 = tuple("hello")
print(t5)
元组的特性
t = (1, 2, 3, 4, 5)
# 访问元素
print("第一个元素:", t[0])
print("最后一个元素:", t[-1])
# 切片操作
print("前三个元素:", t[:3])
print("从索引2开始:", t[2:])
# 元组是不可变的,以下操作会报错
# t[0] = 10 # 会引发TypeError
# 元组的长度
print("长度:", len(t))
# 元组的方法
print("元素2出现的次数:", t.count(2))
print("元素3的索引:", t.index(3))
# 元组的拼接
t1 = (1, 2, 3)
t2 = (4, 5, 6)
t3 = t1 + t2
print("拼接后:", t3)
# 元组的重复
t4 = t1 * 3
print("重复后:", t4)
元组的使用场景
# 作为函数返回值
def get_coordinates():
return (10, 20, 30)
x, y, z = get_coordinates()
print(f"x={x}, y={y}, z={z}")
# 作为字典的键(因为元组是不可变的)
person = {
("John", "Doe"): 30,
("Jane", "Smith"): 25
}
print(person[("John", "Doe")])
# 多变量赋值
a, b, c = (1, 2, 3)
print(f"a={a}, b={b}, c={c}")
# 交换变量值
x, y = 10, 20
print(f"交换前: x={x}, y={y}")
x, y = y, x
print(f"交换后: x={x}, y={y}")
2.3 字典:键值对的集合
字典是Python中另一种重要的数据结构,它存储键值对,允许通过键快速查找值。
创建字典
# 使用大括号创建字典
person = {
"name": "John",
"age": 30,
"city": "New York"
}
print(person)
# 使用dict()函数创建字典
person2 = dict(name="Jane", age=25, city="London")
print(person2)
# 从列表创建字典
items = [("name", "Bob"), ("age", 35), ("city", "Paris")]
person3 = dict(items)
print(person3)
# 创建空字典
empty_dict = {}
print(empty_dict)
字典的基本操作
person = {
"name": "John",
"age": 30,
"city": "New York"
}
# 访问值
print("姓名:", person["name"])
print("年龄:", person.get("age"))
# 使用get()方法避免KeyError
print("职业:", person.get("job", "未知"))
# 添加或修改键值对
person["job"] = "Engineer"
print("添加职业后:", person)
person["age"] = 31
print("修改年龄后:", person)
# 删除键值对
del person["city"]
print("删除城市后:", person)
# 弹出键值对
job = person.pop("job")
print("弹出的职业:", job)
print("弹出后:", person)
# 清空字典
person.clear()
print("清空后:", person)
字典的方法
person = {
"name": "John",
"age": 30,
"city": "New York",
"job": "Engineer"
}
# 获取所有键
print("所有键:", list(person.keys()))
# 获取所有值
print("所有值:", list(person.values()))
# 获取所有键值对
print("所有键值对:", list(person.items()))
# 遍历字典
print("\n遍历键:")
for key in person:
print(key)
print("\n遍历键值对:")
for key, value in person.items():
print(f"{key}: {value}")
# 字典的更新
person.update({"age": 31, "salary": 50000})
print("更新后:", person)
# 字典的复制
person_copy = person.copy()
print("副本:", person_copy)
字典的应用场景
# 存储配置信息
config = {
"host": "localhost",
"port": 8080,
"debug": True,
"database": {
"name": "mydb",
"user": "admin",
"password": "password"
}
}
print("配置信息:", config)
# 统计词频
text = "hello world hello python hello"
word_count = {}
for word in text.split():
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print("词频统计:", word_count)
# 使用字典实现简单的缓存
cache = {}
def get_data(key):
if key in cache:
print("从缓存获取数据")
return cache[key]
else:
print("从数据库获取数据")
# 模拟从数据库获取数据
data = f"数据{key}"
cache[key] = data
return data
print(get_data(1))
print(get_data(1)) # 从缓存获取
print(get_data(2))
2.4 集合:无序的唯一元素集合
集合是一种无序的、包含唯一元素的数据结构,它支持数学中的集合运算。
创建集合
# 使用大括号创建集合
s1 = {1, 2, 3, 4, 5}
print(s1)
# 使用set()函数创建集合
s2 = set([1, 2, 3, 4, 5])
print(s2)
# 从字符串创建集合
s3 = set("hello")
print(s3) # 注意:集合中的元素是唯一的
# 创建空集合(不能用{},因为{}创建的是空字典)
s4 = set()
print(s4)
集合的基本操作
s = {1, 2, 3, 4, 5}
# 添加元素
s.add(6)
print("添加后:", s)
# 添加多个元素
s.update([7, 8, 9])
print("更新后:", s)
# 删除元素
s.remove(9)
print("删除后:", s)
# 弹出元素(随机)
popped = s.pop()
print("弹出的元素:", popped)
print("弹出后:", s)
# 清空集合
s.clear()
print("清空后:", s)
集合的运算
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
# 并集
print("并集:", A | B)
print("并集:", A.union(B))
# 交集
print("交集:", A & B)
print("交集:", A.intersection(B))
# 差集
print("差集(A-B):", A - B)
print("差集(A-B):", A.difference(B))
print("差集(B-A):", B - A)
print("差集(B-A):", B.difference(A))
# 对称差集
print("对称差集:", A ^ B)
print("对称差集:", A.symmetric_difference(B))
# 子集和超集
C = {1, 2, 3}
print("C是A的子集:", C.issubset(A))
print("A是C的超集:", A.issuperset(C))
集合的应用场景
# 去重
numbers = [1, 2, 3, 2, 1, 4, 5, 4]
unique_numbers = list(set(numbers))
print("去重后:", unique_numbers)
# 检查元素是否存在
fruits = {"apple", "banana", "cherry"}
print("apple在集合中:", "apple" in fruits)
print("orange在集合中:", "orange" in fruits)
# 集合运算应用
students_who_took_math = {"Alice", "Bob", "Charlie", "David"}
students_who_took_physics = {"Bob", "David", "Eve", "Frank"}
print("只参加数学的学生:", students_who_took_math - students_who_took_physics)
print("只参加物理的学生:", students_who_took_physics - students_who_took_math)
print("两门都参加的学生:", students_who_took_math & students_who_took_physics)
print("至少参加一门的学生:", students_who_took_math | students_who_took_physics)
2.5 高级操作:数据结构的最佳实践
现在让我们学习一些数据结构的高级操作和最佳实践。
嵌套数据结构
# 列表嵌套
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print("矩阵:", matrix)
print("第二行第三列:", matrix[1][2])
# 字典嵌套
student = {
"name": "John",
"age": 18,
"grades": {
"math": 90,
"english": 85,
"science": 95
},
"hobbies": ["reading", "coding", "sports"]
}
print("学生信息:", student)
print("数学成绩:", student["grades"]["math"])
print("第一个爱好:", student["hobbies"][0])
# 集合嵌套(只能嵌套不可变类型)
set_of_tuples = {(1, 2), (3, 4), (5, 6)}
print("元组集合:", set_of_tuples)
数据结构的选择
# 选择合适的数据结构
# 列表:有序,可修改,允许重复元素
# 用例:需要保持顺序的元素集合
shopping_list = ["apple", "banana", "cherry"]
# 元组:有序,不可修改,允许重复元素
# 用例:需要保持顺序且不希望被修改的数据
coordinates = (10, 20, 30)
# 字典:无序(Python 3.7+有序),键值对,键唯一
# 用例:需要通过键快速查找值的数据
person = {"name": "John", "age": 30}
# 集合:无序,元素唯一
# 用例:需要去重或进行集合运算的数据
unique_numbers = {1, 2, 3, 4, 5}
# 示例:根据场景选择数据结构
# 场景1:存储学生的成绩,需要通过姓名快速查找
grades = {
"Alice": 90,
"Bob": 85,
"Charlie": 95
}
print("Alice的成绩:", grades.get("Alice"))
# 场景2:存储班级所有学生的姓名,需要去重
students = {"Alice", "Bob", "Charlie", "Alice"} # 自动去重
print("学生集合:", students)
# 场景3:存储每周的温度数据,需要保持顺序
temperatures = [22, 25, 23, 24, 26, 27, 28]
print("周四的温度:", temperatures[3])
性能考虑
import time
# 测试列表和集合的成员检查性能
size = 100000
large_list = list(range(size))
large_set = set(range(size))
# 测试列表的成员检查
start = time.time()
for i in range(size):
i in large_list
list_time = time.time() - start
print(f"列表成员检查时间: {list_time:.6f}秒")
# 测试集合的成员检查
start = time.time()
for i in range(size):
i in large_set
set_time = time.time() - start
print(f"集合成员检查时间: {set_time:.6f}秒")
print(f"集合比列表快 {list_time/set_time:.2f} 倍")
# 测试字典的查找性能
large_dict = {i: i for i in range(size)}
start = time.time()
for i in range(size):
large_dict.get(i)
dict_time = time.time() - start
print(f"字典查找时间: {dict_time:.6f}秒")
2.6 单元练习题
太棒了!你已经学完了第二单元的所有内容。现在让我们通过一些练习来巩固所学知识吧!
练习题1:列表操作
编写一个程序,创建一个包含1-10的列表,然后执行以下操作:
- 添加元素11
- 删除元素5
- 将列表反转
- 对列表排序
- 输出最终结果
查看参考答案
# 创建包含1-10的列表
numbers = list(range(1, 11))
print("原始列表:", numbers)
# 添加元素11
numbers.append(11)
print("添加11后:", numbers)
# 删除元素5
numbers.remove(5)
print("删除5后:", numbers)
# 将列表反转
numbers.reverse()
print("反转后:", numbers)
# 对列表排序
numbers.sort()
print("排序后:", numbers)
练习题2:字典操作
编写一个程序,创建一个字典存储学生的姓名和成绩,然后执行以下操作:
- 添加一个新学生
- 修改一个学生的成绩
- 删除一个学生
- 计算所有学生的平均成绩
查看参考答案
# 创建学生成绩字典
student_grades = {
"Alice": 90,
"Bob": 85,
"Charlie": 95
}
print("原始字典:", student_grades)
# 添加一个新学生
student_grades["David"] = 88
print("添加David后:", student_grades)
# 修改一个学生的成绩
student_grades["Bob"] = 87
print("修改Bob的成绩后:", student_grades)
# 删除一个学生
del student_grades["Charlie"]
print("删除Charlie后:", student_grades)
# 计算平均成绩
if student_grades:
average = sum(student_grades.values()) / len(student_grades)
print(f"平均成绩: {average:.2f}")
else:
print("没有学生成绩")
练习题3:集合操作
编写一个程序,创建两个集合,然后执行以下操作:
- 计算并集
- 计算交集
- 计算差集
- 检查一个集合是否是另一个集合的子集
查看参考答案
# 创建两个集合
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
print("集合A:", A)
print("集合B:", B)
# 计算并集
union = A | B
print("并集:", union)
# 计算交集
intersection = A & B
print("交集:", intersection)
# 计算差集
difference1 = A - B
difference2 = B - A
print("A-B:", difference1)
print("B-A:", difference2)
# 检查子集
C = {1, 2, 3}
print("C是A的子集:", C.issubset(A))
print("A是C的子集:", A.issubset(C))
练习题4:嵌套数据结构
创建一个嵌套字典,存储多个学生的信息,包括姓名、年龄、课程和成绩,然后编写代码获取和修改其中的数据。
查看参考答案
# 创建嵌套字典
students = {
"Alice": {
"age": 18,
"courses": {
"math": 90,
"english": 85,
"science": 95
}
},
"Bob": {
"age": 17,
"courses": {
"math": 80,
"english": 75,
"science": 85
}
}
}
# 获取Alice的数学成绩
print("Alice的数学成绩:", students["Alice"]["courses"]["math"])
# 修改Bob的英语成绩
students["Bob"]["courses"]["english"] = 80
print("修改后Bob的英语成绩:", students["Bob"]["courses"]["english"])
# 添加新学生
students["Charlie"] = {
"age": 19,
"courses": {
"math": 95,
"english": 90,
"science": 85
}
}
print("添加Charlie后:", students)
# 计算每个学生的平均成绩
for name, info in students.items():
grades = info["courses"].values()
average = sum(grades) / len(grades)
print(f"{name}的平均成绩: {average:.2f}")
练习题5:数据结构综合应用
编写一个程序,使用列表、字典和集合来统计一段文本中单词的出现次数,并找出出现频率最高的单词。
查看参考答案
text = "Python is a powerful programming language. Python is easy to learn. Python is widely used in data science and web development."
# 预处理文本
text = text.lower()
for char in ". , ! ?":
text = text.replace(char, "")
# 分割单词
words = text.split()
print("所有单词:", words)
# 统计词频
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print("词频统计:", word_count)
# 找出频率最高的单词
if word_count:
max_word = max(word_count, key=word_count.get)
print(f"出现频率最高的单词: '{max_word}',出现了{word_count[max_word]}次")
# 找出唯一单词
unique_words = set(words)
print(f"唯一单词数量: {len(unique_words)}")
print("唯一单词:", unique_words)
单元总结
🎉 恭喜你完成了第二单元的学习!
- 你掌握了列表的高级操作,包括列表推导式和切片
- 你理解了元组的特性和使用场景
- 你学会了使用字典存储和管理键值对数据
- 你掌握了集合的特性和集合运算
- 你学习了数据结构的高级操作和最佳实践
- 你能够根据不同场景选择合适的数据结构
继续加油,下一个单元我们将学习函数与模块!