当前位置:首页>python>【Python】Day11:字典进阶与嵌套

【Python】Day11:字典进阶与嵌套

  • 2026-10-11 07:32:57
【Python】Day11:字典进阶与嵌套

🎯 学习目标

  1. 掌握 字典嵌套:字典的值是字典、字典的值是列表等复合结构
  2. 学会用嵌套字典表达 多层结构化数据(如通讯录、商品目录)
  3. 掌握 字典推导式,快速生成字典
  4. 学会安全地访问嵌套字典,避免KeyError层层传递
  5. 能设计合理的数据结构存储复杂信息,并实现增删改查

一、字典嵌套

  1. 字典的值是字典:两层嵌套
    # 多个学生,每个学生有自己的详细信息students = {"S001": {"name": "小王", "age": 18, "score": 92},"S002": {"name": "小李", "age": 19, "score": 88},"S003": {"name": "小张", "age": 18, "score": 95}}# 访问:先取外层,再取内层print(students["S001"])              # {'name': '小王', 'age': 18, 'score': 92}print(students["S001"]["name"])      # 小王print(students["S002"]["score"])     # 88
  2. 字典的值是列表
    # 每个学生的选课列表courses = {"小王": ["数学", "英语", "编程"],"小李": ["物理", "化学"],"小张": ["数学", "物理", "编程", "英语"]}print(courses["小王"])               # ['数学', '英语', '编程']print(courses["小王"][0])            # 数学(先取列表,再取索引)print(len(courses["小张"]))          # 4(小张选了4门课)# 给小王添加一门课courses["小王"].append("体育")print(courses["小王"])               # ['数学', '英语', '编程', '体育']
  3. 列表中的元素是字典
    # 一组商品,每个商品是一个字典products = [    {"id": 1, "name": "iPhone", "price": 7999},    {"id": 2, "name": "iPad", "price": 3999},    {"id": 3, "name": "MacBook", "price": 12999}]# 遍历每个商品for product in products:    print(f"{product['name']}:¥{product['price']}")# iPhone:¥7999# iPad:¥3999# MacBook:¥12999# 按条件筛选:价格低于5000的cheap = [p for p in products if p["price"] < 5000]print(cheap)    # [{'id': 2, 'name': 'iPad', 'price': 3999}]
  4. 三层嵌套:更复杂的数据结构
    # 学校 → 年级 → 班级 → 学生school = {"初一年级": {"1班": ["小王", "小李", "小张"],"2班": ["赵六", "钱七", "孙八"]    },"初二年级": {"1班": ["周九", "吴十"],"2班": ["郑冬", "王春"]    }}print(school["初一年级"]["1班"])       # ['小王', '小李', '小张']print(school["初一年级"]["1班"][0])    # 小王

二、嵌套结构的增删改查

  1. 增:添加新的键值对或列表元素
    students = {"S001": {"name": "小王", "age": 18, "score": 92}}# 添加一个新学生students["S002"] = {"name": "小李", "age": 19, "score": 88}print(students)# 给已有学生添加新字段students["S001"]["city"] = "北京"print(students["S001"])  # {'name': '小王', 'age': 18, 'score': 92, 'city': '北京'}# 给已有学生添加爱好列表students["S001"]["hobbies"] = ["编程", "阅读"]print(students["S001"])
  2. 删:删除嵌套中的某个字段
    students = {"S001": {"name": "小王", "age": 18, "score": 92, "city": "北京"}}# 删除某个学生的某个字段del students["S001"]["city"]print(students["S001"])  # {'name': '小王', 'age': 18, 'score': 92}# 删除整个学生del students["S001"]print(students)          # {'S002': {'name': '小李', 'age': 19, 'score': 88}}
  3. 改:修改嵌套中的值
    students = {"S001": {"name": "小王", "age": 18, "score": 92}}# 修改分数students["S001"]["score"] = 95print(students["S001"]["score"])   # 95
  4. 查:安全访问嵌套结构
    students = {"S001": {"name": "小王", "age": 18, "score": 92}}# 不安全:如果 S003 不存在,会 KeyError# students["S003"]["name"]        # KeyError: 'S003'# 安全方式一:先判断外层if"S003"in students:    print(students["S003"]["name"])else:    print("未找到该学生")# 安全方式二:链式 getname = students.get("S003", {}).get("name", "未知")print(name)                        # 未知# 安全方式三:try-except(后面会详细学)try:    print(students["S003"]["name"])except KeyError:    print("未找到该学生")

三、遍历嵌套字典

  1. 遍历两层嵌套字典
    students = {"S001": {"name": "小王", "age": 18, "score": 92},"S002": {"name": "小李", "age": 19, "score": 88},"S003": {"name": "小张", "age": 18, "score": 95}}for sid, info in students.items():    print(f"学号:{sid},姓名:{info['name']},分数:{info['score']}")# 学号:S001,姓名:小王,分数:92# 学号:S002,姓名:小李,分数:88# 学号:S003,姓名:小张,分数:95
  2. 遍历列表中的字典
    products = [    {"name": "iPhone", "price": 7999},    {"name": "iPad", "price": 3999},    {"name": "MacBook", "price": 12999}]for i, product in enumerate(products):    print(f"商品{i+1}:{product['name']},价格:¥{product['price']}")
  3. 查找:在嵌套结构中搜索
    students = {"S001": {"name": "小王", "age": 18, "score": 92},"S002": {"name": "小李", "age": 19, "score": 88},"S003": {"name": "小张", "age": 18, "score": 95}}# 找分数最高的学生max_score = 0top_student = ""for sid, info in students.items():if info["score"] > max_score:        max_score = info["score"]        top_student = info["name"]print(f"最高分:{top_student},{max_score}分")   # 最高分:小张,95分# 找所有18岁的学生age_18 = [info["name"] for info in students.values() if info["age"] == 18]print(age_18)              # ['小王', '小张']

四、字典推导式

  1. 基本语法
    # 传统写法squares = {}for x in range(1, 6):    squares[x] = x ** 2print(squares)          # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}# 字典推导式squares = {x: x ** 2for x in range(1, 6)}print(squares)          # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
  2. 实用场景
    # 翻转字典的键和值original = {"a": 1, "b": 2, "c": 3}flipped = {v: k for k, v in original.items()}print(flipped)          # {1: 'a', 2: 'b', 3: 'c'}# 从两个列表创建字典keys = ["name", "age", "city"]values = ["小王", 18, "北京"]info = {k: v for k, v in zip(keys, values)}print(info)             # {'name': '小王', 'age': 18, 'city': '北京'}# 带条件:只保留分数及格的学生scores = {"小王": 92, "小李": 55, "小张": 95, "赵六": 48}passed = {name: score for name, score in scores.items() if score >= 60}print(passed)           # {'小王': 92, '小张': 95}# 给所有商品价格打9折prices = {"苹果": 5.5, "香蕉": 3.8, "橘子": 4.2}discounted = {name: round(price * 0.9, 2) for name, price in prices.items()}print(discounted)       # {'苹果': 4.95, '香蕉': 3.42, '橘子': 3.78}
  3. 推导式模板
    {键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}

五、字典的其他进阶用法

  1. zip()函数:把两个列表"拉链式"配对
    names = ["小王", "小李", "小张"]scores = [92, 88, 95]# 组成字典result = dict(zip(names, scores))print(result)           # {'小王': 92, '小李': 88, '小张': 95}# 也可以遍历for name, score in zip(names, scores):    print(f"{name}: {score}分")
  2. 字典的排序
    scores = {"小王": 92, "小李": 88, "小张": 95, "赵六": 48}# 按值排序(返回列表)sorted_by_score = sorted(scores.items(), key=lambda x: x[1])print(sorted_by_score)# [('赵六', 48), ('小李', 88), ('小王', 92), ('小张', 95)]# 按值降序排序sorted_desc = sorted(scores.items(), key=lambda x: x[1], reverse=True)print(sorted_desc)# [('小张', 95), ('小王', 92), ('小李', 88), ('赵六', 48)]# 排序后转回字典sorted_dict = dict(sorted(scores.items(), key=lambda x: x[1], reverse=True))print(sorted_dict)# {'小张': 95, '小王': 92, '小李': 88, '赵六': 48}

⚠️ 常见坑

  1. 嵌套访问链路中任何一层不存在都会报错
    data = {"S001": {"name": "小王"}}# data["S002"]["name"]              # KeyError: 'S002'# 用链式 get 更安全print(data.get("S002", {}).get("name", "未知"))  # 未知
  2. 嵌套字典的浅拷贝问题
    import copyoriginal = {"S001": {"name": "小王", "score": 92}}# 浅拷贝:内层字典仍然是引用shallow = original.copy()shallow["S001"]["score"] = 0print(original["S001"]["score"])    # 0!原字典也被改了!# 深拷贝:完全独立original = {"S001": {"name": "小王", "score": 92}}deep = copy.deepcopy(original)deep["S001"]["score"] = 0print(original["S001"]["score"])    # 92  原字典没变
  3. 字典推导式中键重复会被覆盖
    words = ["hello", "world", "hi"]d = {w[0]: w for w in words}print(d)    # {'h': 'hi', 'w': 'world'}  "hello" 被 "hi" 覆盖了!
  4. zip()以最短的列表为准
    a = [1, 2, 3, 4]b = ["a", "b", "c"]result = dict(zip(a, b))print(result)   # {1: 'a', 2: 'b', 3: 'c'}  4被丢弃了

✍️ 实战练习

  1. 班级成绩管理
    • 要求:用嵌套字典存储多个学生的信息,实现添加学生、修改分数、查找学生。
    • 示例:
      students = {"S001": {"name": "小王", "score": 92},"S002": {"name": "小李", "score": 88},}# 添加学生students["S003"] = {"name": "小张", "score": 95}# 修改分数students["S001"]["score"] = 98# 查找学生sid = input("请输入学号:")info = students.get(sid)if info:    print(f"姓名:{info['name']},分数:{info['score']}")else:    print("未找到该学生")
  2. 商品库存管理
    • 要求:用字典存储商品信息(名称、价格、库存量),实现降价促销和库存查询。
    • 示例:
      products = {"P001": {"name": "iPhone", "price": 7999, "stock": 50},"P002": {"name": "iPad", "price": 3999, "stock": 30},"P003": {"name": "MacBook", "price": 12999, "stock": 20}}# 全场8折for pid, info in products.items():    info["price"] = round(info["price"] * 0.8, 0)print(products)# 库存不足25的商品low_stock = {pid: info for pid, info in products.items() if info["stock"] < 25}print("库存不足:", low_stock)
  3. 通讯录数据结构设计
    • 要求:设计一个通讯录数据结构,支持按姓名查找电话,每个联系人可以有多个电话号码。
    • 示例:
      contacts = {"小王": {"phones": ["138-0001-0001", "010-12345678"], "city": "北京"},"小李": {"phones": ["139-0002-0002"], "city": "上海"},"小张": {"phones": ["137-0003-0003", "021-87654321", "150-0004-0004"], "city": "广州"}}# 查询name = input("请输入联系人姓名:")info = contacts.get(name)if info:    print(f"城市:{info['city']}")    print(f"电话:{', '.join(info['phones'])}")else:    print("未找到该联系人")
  4. 字典推导式练习
    • 将{"a": 1, "b": 2, "c": 3}的值翻倍
    • 用zip()将两个列表合成字典
    • 从成绩字典中筛选出优秀(≥90)的学生
    • 要求:用字典推导式完成以下任务:
    • 示例:
      # 值翻倍d1 = {k: v * 2for k, v in {"a": 1, "b": 2, "c": 3}.items()}print(d1)               # {'a': 2, 'b': 4, 'c': 6}# zip 合成字典names = ["语文", "数学", "英语"]scores = [85, 92, 78]d2 = dict(zip(names, scores))print(d2)               # {'语文': 85, '数学': 92, '英语': 78}# 筛选优秀all_scores = {"小王": 92, "小李": 85, "小张": 95, "赵六": 78}excellent = {name: score for name, score in all_scores.items() if score >= 90}print(excellent)        # {'小王': 92, '小张': 95}

✅ 自测清单

  • [ ] 能理解并创建嵌套字典(字典中嵌套字典、字典中嵌套列表)
  • [ ] 能用链式索引访问嵌套数据,如data["S001"]["name"]
  • [ ] 能对嵌套结构进行增删改查操作
  • [ ] 能安全访问嵌套数据:链式get()、先判断再访问
  • [ ] 能遍历嵌套字典,用items()取出内外层的数据
  • [ ] 能写出字典推导式,理解{键表达式: 值表达式 for ... if ...}
  • [ ] 知道dict(zip(list1,list2))可以把两个列表配对成字典
  • [ ] 知道浅拷贝.copy()只复制最外层,嵌套结构需要deepcopy()

最新文章

随机文章