跳到主要内容

第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. 列表练习
    • 创建一个包含 1 到 10 的列表
    • 反转列表
    • 排序列表
    • 添加元素 11
    • 删除元素 5
  2. 元组练习
    • 创建一个包含姓名、年龄、城市的元组
    • 访问元组中的元素
    • 计算元组的长度
  3. 字典练习
    • 创建一个表示学生信息的字典
    • 添加新的键值对
    • 修改现有值
    • 删除一个键值对
    • 遍历字典
  4. 集合练习
    • 创建两个集合,计算它们的并集、交集和差集
    • 向集合中添加元素
    • 从集合中删除元素
  5. 综合练习:编写一个程序,使用字典存储学生的成绩,然后计算平均分

6.9 小结

本章我们学习了:

  • 列表(List)的创建、访问、修改和操作
  • 元组(Tuple)的创建、访问和操作
  • 字典(Dictionary)的创建、访问、修改和操作
  • 集合(Set)的创建、操作和集合运算
  • 数据结构的选择
  • 综合示例

现在你已经掌握了 Python 的基本数据结构,可以开始学习 Python 的文件操作了!