课程 17:嵌套数据结构
1. 嵌套数据结构基础
1.1 概念与意义
定义: 嵌套数据结构是指列表、字典等容器中还包含其他容器。常见有:二维/三维列表、字典的字典、列表中嵌套字典、树结构、JSON等。
意义: 嵌套结构能表达更复杂的数据关系,如表格、树、图、配置、分层菜单、JSON数据等。
# 二维列表(表格/矩阵)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 三维列表(立体数据/多张表)
cube = [[[1,2],[3,4]], [[5,6],[7,8]]]
# 树结构(用嵌套字典/列表表示)
tree = {'value': 1, 'children': [{'value': 2}, {'value': 3}]}
# JSON数据(本质是嵌套字典和列表)
1.2 创建与访问嵌套结构
# 嵌套列表
scores = [[90, 85], [88, 92], [75, 80]]
print(scores[1][0]) # 88
# 嵌套字典
students = {
'Alice': {'math': 90, 'eng': 85},
'Bob': {'math': 88, 'eng': 92}
}
print(students['Bob']['eng']) # 92
# 列表中嵌套字典
users = [
{'name': 'Alice', 'age': 20},
{'name': 'Bob', 'age': 21}
]
print(users[0]['name']) # Alice
常用操作:
• 多层索引访问:结构[外层][内层]
• 动态添加/修改/删除嵌套元素
• 嵌套结构的插入、拷贝、合并
# 修改嵌套元素
scores[0][1] = 95
students['Alice']['math'] = 100
# 插入新元素
scores.append([82, 88])
students['Tom'] = {'math': 80, 'eng': 78}
# 删除元素
del students['Bob']['eng']
1.3 深拷贝与浅拷贝
浅拷贝: 只复制最外层,嵌套对象仍然共享。
深拷贝: 递归复制所有层级,互不影响。
import copy
lst = [[1,2],[3,4]]
shallow = lst.copy()
deep = copy.deepcopy(lst)
shallow[0][0] = 99
print(lst) # [[99, 2], [3, 4]]
print(deep) # [[1, 2], [3, 4]]
2. 遍历与处理嵌套结构
2.1 遍历嵌套列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i, row in enumerate(matrix):
for j, item in enumerate(row):
print(f"matrix[{i}][{j}] = {item}")
2.2 遍历嵌套字典
students = {
'Alice': {'math': 90, 'eng': 85},
'Bob': {'math': 88, 'eng': 92}
}
for name, subjects in students.items():
for subject, score in subjects.items():
print(f"{name} {subject}: {score}")
2.3 递归遍历多层嵌套
# 递归打印任意层嵌套列表
def print_nested(lst, level=0):
for item in lst:
if isinstance(item, list):
print_nested(item, level+1)
else:
print(' '*level + str(item))
print_nested([1, [2, [3, 4]], 5])
2.4 扁平化嵌套列表
# flatten: 将多层嵌套列表拉平成一维
def flatten(lst):
result = []
for item in lst:
if isinstance(item, list):
result.extend(flatten(item))
else:
result.append(item)
return result
print(flatten([1, [2, [3, 4]], 5])) # [1, 2, 3, 4, 5]
不规则嵌套: 处理时需判断类型,递归是通用方法。
3. 嵌套结构的实际应用
3.1 统计与分析
# 统计每个学生的平均分
students = {
'Alice': {'math': 90, 'eng': 85, 'cs': 95},
'Bob': {'math': 88, 'eng': 92, 'cs': 80}
}
for name, subjects in students.items():
avg = sum(subjects.values()) / len(subjects)
print(f"{name} 平均分: {avg:.2f}")
3.2 树结构与多级菜单
# 用嵌套字典/列表表示树结构
menu = [
{'name': '文件', 'children': [
{'name': '新建'}, {'name': '打开'}
]},
{'name': '编辑', 'children': [
{'name': '复制'}, {'name': '粘贴'}
]}
]
def print_menu(menu, level=0):
for item in menu:
print(' '*level + item['name'])
if 'children' in item:
print_menu(item['children'], level+1)
print_menu(menu)
3.3 JSON数据解析与导出
import json
# 嵌套结构转JSON
books = [
{'title': 'Python入门', 'author': '张三', 'price': 59.9},
{'title': '数据结构', 'author': '李四', 'price': 69.0}
]
json_str = json.dumps(books, ensure_ascii=False, indent=2)
print(json_str)
# JSON转嵌套结构
books2 = json.loads(json_str)
print(books2)
3.4 复杂查找与筛选
# 查找所有价格大于60的书
expensive_books = [book for book in books if book['price'] > 60]
print(expensive_books)
4. 嵌套结构的常见错误与调试
- 索引/键不存在会抛出
IndexError 或 KeyError
- 嵌套层数不一致导致遍历出错
- 深拷贝与浅拷贝问题(修改嵌套对象时需注意)
# 防御式访问嵌套字典
def get_score(students, name, subject):
return students.get(name, {}).get(subject, None)
print(get_score(students, 'Alice', 'math')) # 90
print(get_score(students, 'Tom', 'math')) # None
# defaultdict自动嵌套字典
from collections import defaultdict
def tree():
return defaultdict(tree)
data = tree()
data['a']['b']['c'] = 1
print(dict(data))
# pprint美观打印嵌套结构
from pprint import pprint
pprint(students)
5. 可视化与调试技巧
5.1 递归打印树状结构
def print_tree(data, level=0):
if isinstance(data, dict):
for k, v in data.items():
print(' '*level + str(k))
print_tree(v, level+1)
elif isinstance(data, list):
for item in data:
print_tree(item, level+1)
else:
print(' '*level + str(data))
print_tree(students)
5.2 JSON格式化输出
print(json.dumps(students, ensure_ascii=False, indent=2))
学习建议:嵌套数据结构是处理复杂数据的基础,建议多动手实践,理解其访问和遍历方式,遇到报错要学会调试和查文档。推荐多用 pprint、json.dumps、递归等工具辅助调试和可视化。
思考题:嵌套数据结构有哪些典型应用场景?如何优雅地处理多层嵌套的数据?在实际开发中,如何选择合适的数据结构?深拷贝和浅拷贝在嵌套结构中有何影响?