第6章:Python 数据结构
6.1 列表(List)
列表是 Python 中最常用的数据结构之一,用于存储有序的元素集合。
列表的创建
# 创建空列表
empty_list = []
empty_list = list()
# 创建带有元素的列表
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "apple", 3.14, True]
# 使用 range() 创建列表
numbers = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 列表推导式
squares = [x ** 2 for x in range(5)] # [0, 1, 4, 9, 16]
列表的访问
fruits = ["apple", "banana", "cherry"]
# 通过索引访问
print(fruits[0]) # "apple"
print(fruits[-1]) # "cherry" (负数索引从末尾开始)
# 切片
print(fruits[0:2]) # ["apple", "banana"]
print(fruits[1:]) # ["banana", "cherry"]
print(fruits[:2]) # ["apple", "banana"]
print(fruits[::2]) # ["apple", "cherry"]
print(fruits[::-1]) # ["cherry", "banana", "apple"] (反转列表)
列表的修改
fruits = ["apple", "banana", "cherry"]
# 修改元素
fruits[1] = "orange"
print(fruits) # ["apple", "orange", "cherry"]
# 添加元素
fruits.append("grape") # 在末尾添加
print(fruits) # ["apple", "orange", "cherry", "grape"]
fruits.insert(1, "pear") # 在指定位置插入
print(fruits) # ["apple", "pear", "orange", "cherry", "grape"]
# 扩展列表
more_fruits = ["kiwi", "mango"]
fruits.extend(more_fruits)
print(fruits) # ["apple", "pear", "orange", "cherry", "grape", "kiwi", "mango"]
# 删除元素
fruits.remove("orange") # 删除指定值的元素
print(fruits) # ["apple", "pear", "cherry", "grape", "kiwi", "mango"]
popped = fruits.pop() # 删除并返回末尾元素
print(popped) # "mango"
print(fruits) # ["apple", "pear", "cherry", "grape", "kiwi"]
popped = fruits.pop(1) # 删除并返回指定位置的元素
print(popped) # "pear"
print(fruits) # ["apple", "cherry", "grape", "kiwi"]
# 清空列表
fruits.clear()
print(fruits) # []
列表的操作
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
# 排序
numbers.sort()
print(numbers) # [1, 1, 2, 3, 4, 5, 6, 9]
# 反转
numbers.reverse()
print(numbers) # [9, 6, 5, 4, 3, 2, 1, 1]
# 计数
count = numbers.count(1)
print(count) # 2
# 查找索引
index = numbers.index(5)
print(index) # 2
# 长度
length = len(numbers)
print(length) # 8
# 最大值
max_value = max(numbers)
print(max_value) # 9
# 最小值
min_value = min(numbers)
print(min_value) # 1
# 总和
sum_value = sum(numbers)
print(sum_value) # 31
6.2 元组(Tuple)
元组是不可变的有序元素集合,与列表类似但不能修改。
元组的创建
# 创建元组
empty_tuple = ()
empty_tuple = tuple()
# 创建带有元素的元组
fruits = ("apple", "banana", "cherry")
numbers = (1, 2, 3, 4, 5)
mixed = (1, "apple", 3.14, True)
# 单元素元组(需要加逗号)
single_element = ("apple",)
print(type(single_element)) # <class 'tuple'>
# 没有括号的元组
tuple_without_parens = "apple", "banana", "cherry"
print(type(tuple_without_parens)) # <class 'tuple'>
# 转换为元组
list_to_tuple = tuple([1, 2, 3])
print(list_to_tuple) # (1, 2, 3)
string_to_tuple = tuple("hello")
print(string_to_tuple) # ('h', 'e', 'l', 'l', 'o')
元组的访问
fruits = ("apple", "banana", "cherry")
# 通过索引访问
print(fruits[0]) # "apple"
print(fruits[-1]) # "cherry"
# 切片
print(fruits[0:2]) # ("apple", "banana")
print(fruits[1:]) # ("banana", "cherry")
print(fruits[:2]) # ("apple", "banana")
元组的操作
numbers = (3, 1, 4, 1, 5, 9, 2, 6)
# 长度
length = len(numbers)
print(length) # 8
# 计数
count = numbers.count(1)
print(count) # 2
# 查找索引
index = numbers.index(5)
print(index) # 4
# 最大值
max_value = max(numbers)
print(max_value) # 9
# 最小值
min_value = min(numbers)
print(min_value) # 1
# 总和
sum_value = sum(numbers)
print(sum_value) # 31
# 元组连接
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
combined = tuple1 + tuple2
print(combined) # (1, 2, 3, 4, 5, 6)
# 元组重复
tuple3 = tuple1 * 2
print(tuple3) # (1, 2, 3, 1, 2, 3)
元组的不可变性
# 元组是不可变的,不能修改元素
fruits = ("apple", "banana", "cherry")
try:
fruits[1] = "orange" # 会报错
except TypeError as e:
print(f"Error: {e}")
# 但如果元组包含可变对象,可以修改可变对象的内容
nested = ([1, 2, 3], "apple")
nested[0].append(4)
print(nested) # ([1, 2, 3, 4], "apple")
6.3 字典(Dictionary)
字典是键值对的无序集合,用于存储映射关系。
字典的创建
# 创建空字典
empty_dict = {}
empty_dict = dict()
# 创建带有元素的字典
person = {
"name": "John",
"age": 30,
"city": "New York"
}
# 使用 dict() 函数
person = dict(name="John", age=30, city="New York")
# 从键值对列表创建
pairs = [("name", "John"), ("age", 30), ("city", "New York")]
person = dict(pairs)
# 从两个列表创建
keys = ["name", "age", "city"]
values = ["John", 30, "New York"]
person = dict(zip(keys, values))
字典的访问
person = {"name": "John", "age": 30, "city": "New York"}
# 通过键访问
print(person["name"]) # "John"
print(person["age"]) # 30
# 使用 get() 方法
print(person.get("name")) # "John"
print(person.get("gender", "Unknown")) # "Unknown" (键不存在时返回默认值)
# 检查键是否存在
if "name" in person:
print("Name exists")
if "gender" not in person:
print("Gender does not exist")
字典的修改
person = {"name": "John", "age": 30, "city": "New York"}
# 添加或修改键值对
person["gender"] = "Male"
print(person) # {"name": "John", "age": 30, "city": "New York", "gender": "Male"}
person["age"] = 31
print(person) # {"name": "John", "age": 31, "city": "New York", "gender": "Male"}
# 删除键值对
removed_value = person.pop("gender")
print(removed_value) # "Male"
print(person) # {"name": "John", "age": 31, "city": "New York"}
# 删除所有键值对
person.clear()
print(person) # {}
字典的操作
person = {"name": "John", "age": 30, "city": "New York"}
# 获取所有键
keys = person.keys()
print(list(keys)) # ["name", "age", "city"]
# 获取所有值
values = person.values()
print(list(values)) # ["John", 30, "New York"]
# 获取所有键值对
items = person.items()
print(list(items)) # [("name", "John"), ("age", 30), ("city", "New York")]
# 遍历字典
print("Keys:")
for key in person:
print(key)
print("Values:")
for value in person.values():
print(value)
print("Items:")
for key, value in person.items():
print(f"{key}: {value}")
# 字典长度
length = len(person)
print(length) # 3
字典的高级操作
# 合并字典
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
# Python 3.5+
merged = {**dict1, **dict2}
print(merged) # {"a": 1, "b": 3, "c": 4}
# Python 3.9+
merged = dict1 | dict2
print(merged) # {"a": 1, "b": 3, "c": 4}
# 更新字典
dict1.update(dict2)
print(dict1) # {"a": 1, "b": 3, "c": 4}
# 字典推导式
squares = {x: x ** 2 for x in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 条件字典推导式
even_squares = {x: x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
6.4 集合(Set)
集合是无序的唯一元素集合,用于存储不重复的元素。
集合的创建
# 创建空集合
empty_set = set() # 注意:{} 创建的是空字典
# 创建带有元素的集合
fruits = {"apple", "banana", "cherry"}
numbers = {1, 2, 3, 4, 5}
mixed = {1, "apple", 3.14, True}
# 转换为集合
list_to_set = set([1, 2, 2, 3, 3, 3])
print(list_to_set) # {1, 2, 3} (自动去重)
string_to_set = set("hello")
print(string_to_set) # {'h', 'e', 'l', 'o'} (自动去重)
# 使用 set() 函数
set_from_range = set(range(5))
print(set_from_range) # {0, 1, 2, 3, 4}
集合的操作
fruits = {"apple", "banana", "cherry"}
# 添加元素
fruits.add("grape")
print(fruits) # {"apple", "banana", "cherry", "grape"}
# 添加多个元素
fruits.update(["kiwi", "mango"])
print(fruits) # {"apple", "banana", "cherry", "grape", "kiwi", "mango"}
# 删除元素
fruits.remove("banana") # 如果元素不存在会报错
print(fruits) # {"apple", "cherry", "grape", "kiwi", "mango"}
fruits.discard("orange") # 如果元素不存在不会报错
print(fruits) # {"apple", "cherry", "grape", "kiwi", "mango"}
popped = fruits.pop() # 随机删除并返回一个元素
print(popped)
print(fruits)
# 清空集合
fruits.clear()
print(fruits) # set()
集合的运算
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
# 并集
union = set1 | set2
print(union) # {1, 2, 3, 4, 5, 6, 7, 8}
# 交集
intersection = set1 & set2
print(intersection) # {4, 5}
# 差集
difference = set1 - set2
print(difference) # {1, 2, 3}
# 对称差集(并集减去交集)
symmetric_difference = set1 ^ set2
print(symmetric_difference) # {1, 2, 3, 6, 7, 8}
# 子集检查
set3 = {1, 2, 3}
print(set3.issubset(set1)) # True
# 超集检查
print(set1.issuperset(set3)) # True
# 不相交检查
set4 = {6, 7, 8}
print(set1.isdisjoint(set4)) # True
6.5 数据结构的选择
| 数据结构 | 特点 | 适用场景 |
|---|---|---|
| 列表 | 有序、可变、允许重复 | 需要存储有序元素,需要频繁修改 |
| 元组 | 有序、不可变、允许重复 | 需要存储不可变的有序元素,作为字典键 |
| 字典 | 无序、可变、键唯一 | 需要存储键值对,根据键快速查找 |
| 集合 | 无序、可变、元素唯一 | 需要存储唯一元素,需要集合运算 |
6.6 综合示例
示例1:学生管理系统
# 学生管理系统
students = []
# 添加学生
def add_student(name, age, grade):
student = {
"name": name,
"age": age,
"grade": grade
}
students.append(student)
print(f"Added student: {name}")
# 查找学生
def find_student(name):
for student in students:
if student["name"] == name:
return student
return None
# 更新学生信息
def update_student(name, age=None, grade=None):
student = find_student(name)
if student:
if age is not None:
student["age"] = age
if grade is not None:
student["grade"] = grade
print(f"Updated student: {name}")
else:
print(f"Student {name} not found")
# 删除学生
def delete_student(name):
global students
students = [student for student in students if student["name"] != name]
print(f"Deleted student: {name}")
# 显示所有学生
def show_all_students():
if not students:
print("No students found")
else:
for student in students:
print(f"Name: {student['name']}, Age: {student['age']}, Grade: {student['grade']}")
# 测试
add_student("John", 15, "10th")
add_student("Alice", 16, "11th")
add_student("Bob", 14, "9th")
print("\nAll students:")
show_all_students()
print("\nFinding John:")
john = find_student("John")
if john:
print(f"Found: {john}")
print("\nUpdating John's age:")
update_student("John", age=16)
print("\nAll students after update:")
show_all_students()
print("\nDeleting Bob:")
delete_student("Bob")
print("\nAll students after deletion:")
show_all_students()
示例2:购物车管理
# 购物车管理
cart = []
# 添加商品
def add_item(name, price, quantity=1):
# 检查商品是否已在购物车中
for item in cart:
if item["name"] == name:
item["quantity"] += quantity
print(f"Updated {name} quantity to {item['quantity']}")
return
# 添加新商品
item = {
"name": name,
"price": price,
"quantity": quantity
}
cart.append(item)
print(f"Added {quantity} x {name} to cart")
# 移除商品
def remove_item(name):
global cart
cart = [item for item in cart if item["name"] != name]
print(f"Removed {name} from cart")
# 更新商品数量
def update_quantity(name, quantity):
for item in cart:
if item["name"] == name:
if quantity <= 0:
remove_item(name)
else:
item["quantity"] = quantity
print(f"Updated {name} quantity to {quantity}")
return
print(f"Item {name} not found in cart")
# 计算总价
def calculate_total():
total = 0
for item in cart:
total += item["price"] * item["quantity"]
return total
# 显示购物车
def show_cart():
if not cart:
print("Cart is empty")
else:
print("Shopping Cart:")
for item in cart:
subtotal = item["price"] * item["quantity"]
print(f"{item['name']}: ${item['price']} x {item['quantity']} = ${subtotal}")
total = calculate_total()
print(f"Total: ${total}")
# 测试
add_item("Apple", 1.99, 3)
add_item("Banana", 0.99, 5)
add_item("Apple", 1.99, 2) # 测试更新数量
print("\nShopping cart:")
show_cart()
print("\nUpdating banana quantity:")
update_quantity("Banana", 3)
print("\nShopping cart after update:")
show_cart()
print("\nRemoving apple:")
remove_item("Apple")
print("\nShopping cart after removal:")
show_cart()
6.7 常见问题和解决方案
问题1:列表索引越界
# 错误示例
fruits = ["apple", "banana", "cherry"]
print(fruits[10]) # 索引越界错误
# 解决方案
try:
print(fruits[10])
except IndexError:
print("Index out of range")
# 检查长度
if len(fruits) > 10:
print(fruits[10])
else:
print("Index out of range")
问题2:字典键不存在
# 错误示例
person = {"name": "John", "age": 30}
print(person["gender"]) # 键不存在错误
# 解决方案
# 使用 get() 方法
print(person.get("gender", "Unknown")) # "Unknown"
# 检查键是否存在
if "gender" in person:
print(person["gender"])
else:
print("Gender not found")
问题3:集合元素必须可哈希
# 错误示例
my_set = {[1, 2, 3]} # 列表不可哈希,会报错
# 解决方案
my_set = {(1, 2, 3)} # 使用元组
my_set = {frozenset([1, 2, 3])} # 使用 frozenset
6.8 练习
- 列表练习:
- 创建一个包含 1 到 10 的列表
- 反转列表
- 排序列表
- 添加元素 11
- 删除元素 5
- 元组练习:
- 创建一个包含姓名、年龄、城市的元组
- 访问元组中的元素
- 计算元组的长度
- 字典练习:
- 创建一个表示学生信息的字典
- 添加新的键值对
- 修改现有值
- 删除一个键值对
- 遍历字典
- 集合练习:
- 创建两个集合,计算它们的并集、交集和差集
- 向集合中添加元素
- 从集合中删除元素
- 综合练习:编写一个程序,使用字典存储学生的成绩,然后计算平均分
6.9 小结
本章我们学习了:
- 列表(List)的创建、访问、修改和操作
- 元组(Tuple)的创建、访问和操作
- 字典(Dictionary)的创建、访问、修改和操作
- 集合(Set)的创建、操作和集合运算
- 数据结构的选择
- 综合示例
现在你已经掌握了 Python 的基本数据结构,可以开始学习 Python 的文件操作了!