--- fid: 20231204-165805 tags: dict, dict basic --- # Dict 字典 Tutorial 1 2025-11-25更新 上次课我们用 2维 List 进行成绩合并,非常不便。这次课我们引用一种更合适的复合型数据类型, 可以更好的处理复杂数据结构,查找复杂度为 O(1)。 本讲义只涉及最核心概念,更多的 dict 方法,见 [tutorial 2](dict-tutorial-2.md)。 **难度**: 1 **时长**: 45 min ## Dict 概念 Dict 是开发稍微复杂一点程序的基础性数据结构。 - 字典以 **键:值** 对的形式的数据值,类似于《新华字典》 - 字典是一个有序的、可更改、且 key不允许重复的集合。 ```python dict = {key: value, key2: value, ...} ``` ![插图](images/dict-book_yp2cwpfq.png) ## Dict 基础 ### 字典成员 (Dictionary Items) **字典成员** 以 `Key:Value` (键:值) 对的形式呈现,可通过键名进行引用。预测每个 print 的输出。 ```python thisdict = { "brand": "Ford", "year": 1960 } print(thisdict) print(thisdict["brand"]) ``` [problem 1] 将下面的列表数据改写转换成 dict 数据 ```python # 语文老师提供 chinese_scores = [["张三", "S001", 85], ["李四", "S002", 92], ["王五", "S003", 78]] # 数学老师提供 math_scores = [["张三", "S001", 90], ["李四", "S002", 87], ["王五", "S003", 85]] # 英语老师提供 english_scores = [["S001", "张三", 88], ["S002", "李四", 85], ["S003", "王五", 80]] ``` 以学号为 key 建立字典 ```python # 问题1解决方案 # 列表1转换 chinese_dict = {item[1]: ... for item in chinese_scores} # 学号:分数 math_dict = {...: item[2] for item in math_scores} english_dict = {...: ... for item in english_scores} ``` ``````{only} show_answer ```python chinese_dict = {item[1]: item[2] for item in chinese_scores} # 学号:分数 math_dict = {item[1]: item[2] for item in math_scores} english_dict = {item[0]: item[2] for item in english_scores} ``` `````` [problem 2] 将下面的列表数据改写转换成 dict 数据 ```python [ ["学号", "姓名", "语文", "数学", "英语"], ["S001", "张三", 85, 90, 88], ["S002", "李四", 92, 87, 85], ["S003", "王五", 78, 85, 80] ] ``` 使用下面的字典结构转换 ```python # 建议说明这种嵌套字典的优势 students_data = { "S001": {"姓名": "张三", "语文": 85, "数学": 90, "英语": 88}, # ... 便于按学号快速查找学生所有信息 } ``` 补全 ... 处的代码: ```python # 列表2转换(更实用的结构) students_data = {} headers = data[0] # ["学号", "姓名", "语文", "数学", "英语"] for row in data[1:]: student_id = row[0] students_data[student_id] = { "姓名": row[1], // ... : row[2], // "数学": ..., // ... : ... // } ``` ``````{only} show_answer ```python "姓名": row[1], "语文": row[2], "数学": row[3], "英语": row[4] ``` `````` ### 顺序性 ```python thisdict["model"] = "Mustang" print(thisdict) ``` **Ordered or Unordered?** Python Dict 有序但又无序,**Unordered:** 不能按 index 访问成员。**Ordered:** 新增加成员,不会改变成员的顺序。[^ordered-dict] - 有序:保持插入顺序(Python 3.7+) - 无序:不能通过数字索引访问 [^ordered-dict]: 从 Python 3.7 版开始,字典是有序的。在 Python 3.6 及更早版本中,字典是无序的。新增加的成员会破原已有成员的顺序。 ### 可更改 (Changeable) 字典是可更改的,这意味着我们可以在创建字典后更改、添加或删除项目。 ```python thisdict["year"] = 1964 print(thisdict) ``` ### 不允许重复(Duplicates Not Allowed) ```python thisdict = { "brand": "Ford", "model": "Mustang", "year": 1964, "year": 2020 # 重复的 key } print(thisdict) ``` 规则: 根据顺序性和可写性,所以后面的定义覆盖前面的定义。 ### Updating Existing Keys ```python title:"" dict['new-key'] = value dict['new-key'] = new_value ``` ### Dict Length ```python print(len(thisdict)) ``` ### Dict value type ```python thisdict = { "brand": "Ford", "electric": False, "year": 1964, "colors": ["red", "white", "blue"] #/// value compound type } ``` 重要概念: - 字典的key必须是不可变类型(字符串、数字、元组) - 字典的value可以是任意类型 [problem03] ``` # 给定初始字典 student = {"name": "zhang", "id": 103, "score": 85} # 1. 添加新键值对:添加 "class": "A班" # 2. 修改值:将score改为90 # 3. 删除键:删除score键 # 4. 检查存在:检查"age"键是否存在 # 5. 获取所有键:打印所有键名 ``` ## 初始化 dict() Constructor ### From keywords args ```python thisdict = dict(name = "John", age = 36, country = "Norway") print(thisdict) ``` ### From key-value pairs separated by comma ```python d = { : , : , . : } ``` ### From lists of key-value tuples ```python d = dict([ (, ), (, , ) ]) ``` [problem04] 有列表记录 `students = [("zhang", 103), ("li", 101), (“wang”, 102)]` ,使用以上三种方法进行初始化 ## 字典遍历 ### loop by key ```python title:"" for key in dict: print(key) ``` ### loop by values ```python title:"" for value in dict.values(): print(value) ``` ### loop by (key, value) ```python title:"" for key, value in dict.items(): print(key, value) ``` 练习: 用上面3种语法打印 students 字典的所有键、值,以及键值对。 [problem05] ``` student_info = {"name": "li", "id": 101, "score": 88, "class": "B班"} # 1. 遍历所有键并打印 # 2. 遍历所有值并打印 # 3. 遍历所有键值对并格式化输出:"姓名: li, 学号: 101" ``` ## 综合练习 ### 复杂功能 dict [problem06] 有列表记录 `students = [("zhang", 103), ("li", 101), (“wang”, 102), ...]`,其中每条记录的第一个字段是姓名,第二个字段是学号。要求: 1. 创建字典,能由学生的姓名查出其学号 2. 创建字典,能由学生学号查出其姓名 3. 创建一个由字典组成的列表,能够通过 `stu[1]['name']` 可以取出学生的姓名 `"li"`,能通过 `stu[2]['id']` 取出学生的学号 `102` 4. (选做)创建一个对象,能由其姓名或学号均能查出和修取其中的成员 ### 表格合并案例 [](pb-list-merge-by-dict-1.md) ## Reference - [Python Dictionaries @ w3schools.com](https://www.w3schools.com/python/python_dictionaries.asp)