From 30be6923edb2e0b1ee94095b826179cb674cbb8d Mon Sep 17 00:00:00 2001 From: "zhiye.sun" Date: Tue, 28 Jul 2026 16:19:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(python=E5=9F=BA=E7=A1=80):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=88=97=E8=A1=A8=E6=95=99=E5=AD=A6=E8=AF=BE=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01_python基础/1_8_列表/README.md | 489 ++++++++++++++++++ 01_python基础/1_8_列表/lists.py | 100 ++++ 01_python基础/1_8_列表/practice.py | 95 ++++ AGENTS.md | 3 + README.md | 10 +- .../specs/2026-07-27-第八课列表-design.md | 117 +++++ 6 files changed, 809 insertions(+), 5 deletions(-) create mode 100644 01_python基础/1_8_列表/README.md create mode 100644 01_python基础/1_8_列表/lists.py create mode 100644 01_python基础/1_8_列表/practice.py create mode 100644 docs/superpowers/specs/2026-07-27-第八课列表-design.md diff --git a/01_python基础/1_8_列表/README.md b/01_python基础/1_8_列表/README.md new file mode 100644 index 0000000..54cf650 --- /dev/null +++ b/01_python基础/1_8_列表/README.md @@ -0,0 +1,489 @@ +# 第 1-8 课:列表 + +## 一、本课目标 + +完成本课后,你应该能够: + +1. 解释列表为什么可以保存多个数据; +2. 创建列表和空列表; +3. 使用索引、负索引和切片读取列表; +4. 修改列表中的指定元素; +5. 添加和删除列表元素; +6. 查找并统计列表中的元素; +7. 对列表进行排序和反转; +8. 使用循环遍历列表; +9. 在确实需要位置时使用索引遍历; +10. 理解列表可变性; +11. 区分直接赋值与列表复制; +12. 看懂简单的二维列表。 + +## 二、前置知识 + +开始本课前,你应该已经掌握: + +- 变量和基础数据类型; +- 字符串的索引与切片; +- `if` 条件判断; +- `for` 循环; +- `in` 成员判断; +- 字符串的 `split()` 和 `join()`。 + +## 三、为什么需要列表 + +如果要保存多个 Agent 开发工具,可以分别创建变量: + +```python +tool_1 = "Python" +tool_2 = "FastAPI" +tool_3 = "Django" +``` + +数据增加后,这种方式难以统一遍历、排序和管理。 + +列表(List)可以使用一个变量保存多个有顺序的数据: + +```python +agent_tools = ["Python", "FastAPI", "Django"] +``` + +列表使用英文方括号 `[]`,元素之间使用英文逗号分隔。 + +## 四、创建列表 + +### 4.1 创建包含数据的列表 + +```python +agent_tools = ["Python", "FastAPI", "Django"] +``` + +### 4.2 创建空列表 + +```python +agent_tools = [] +``` + +空列表暂时没有元素,但后续可以添加数据。 + +### 4.3 列表可以保存不同类型 + +```python +learning_record = ["Python", 8, 2.5, True] +``` + +Python 允许一个列表保存不同类型的数据。不过实际开发中,同一个列表通常保存含义相近的数据,这样更容易理解和处理。 + +## 五、列表是有顺序的 + +列表中的每个元素都有位置,索引从 `0` 开始: + +```text +元素: Python FastAPI Django +正索引: 0 1 2 +负索引: -3 -2 -1 +``` + +读取元素: + +```python +agent_tools = ["Python", "FastAPI", "Django"] + +print(agent_tools[0]) +print(agent_tools[-1]) +``` + +输出: + +```text +Python +Django +``` + +如果访问不存在的索引,会产生 `IndexError`。 + +## 六、列表切片 + +列表切片与字符串切片规则相同:包含开始索引,不包含结束索引。 + +```python +agent_tools = ["Python", "FastAPI", "Django", "LangChain"] + +print(agent_tools[0:2]) +print(agent_tools[:3]) +print(agent_tools[2:]) +print(agent_tools[::-1]) +``` + +切片返回一个新列表,不会直接修改原列表。 + +## 七、列表长度 + +使用 `len()` 获取元素数量: + +```python +agent_tools = ["Python", "FastAPI", "Django"] +tool_count = len(agent_tools) + +print(tool_count) +``` + +输出为 `3`。 + +访问首尾元素前,可以先判断列表是否非空: + +```python +if agent_tools: + print(agent_tools[0]) + print(agent_tools[-1]) +else: + print("工具列表为空") +``` + +空列表在条件中会被当作 `False`。 + +## 八、列表是可变的 + +字符串不可变,但列表是可变的(Mutable),可以直接修改某个位置的元素: + +```python +agent_tools = ["Python", "Flask", "Django"] +agent_tools[1] = "FastAPI" + +print(agent_tools) +``` + +输出: + +```text +['Python', 'FastAPI', 'Django'] +``` + +必须确保索引存在,不能通过一个超出范围的索引直接添加元素。 + +## 九、添加元素 + +### 9.1 `append()` 追加到末尾 + +```python +agent_tools = ["Python", "FastAPI"] +agent_tools.append("Django") +``` + +`append()` 每次把一个元素添加到列表末尾。 + +### 9.2 `insert()` 插入指定位置 + +```python +agent_tools.insert(1, "Pydantic") +``` + +第一个参数是插入索引,第二个参数是新元素。原来位于该位置及后面的元素会向后移动。 + +### 9.3 `extend()` 添加多个元素 + +```python +agent_tools.extend(["LangChain", "OpenAI SDK"]) +``` + +`extend()` 会依次加入另一个列表中的元素。 + +请比较: + +```python +agent_tools.append(["LangChain", "OpenAI SDK"]) +``` + +`append()` 会把整个列表当作一个元素加入,形成嵌套列表;`extend()` 才是逐个加入多个元素。 + +## 十、删除元素 + +### 10.1 `remove()` 按内容删除 + +```python +agent_tools.remove("Django") +``` + +`remove()` 删除第一个匹配的元素。如果元素不存在,会产生 `ValueError`。 + +安全写法: + +```python +if "Django" in agent_tools: + agent_tools.remove("Django") +``` + +### 10.2 `pop()` 按位置删除并返回元素 + +```python +removed_tool = agent_tools.pop() +``` + +不传索引时删除最后一个元素,并把被删除的数据返回。 + +```python +removed_tool = agent_tools.pop(1) +``` + +传入索引时删除指定位置。 + +### 10.3 `del` 删除指定位置 + +```python +del agent_tools[0] +``` + +`del` 是 Python 关键字,不会返回被删除的数据。 + +### 10.4 `clear()` 清空列表 + +```python +agent_tools.clear() +``` + +执行后列表仍然存在,但元素数量变为 `0`。 + +## 十一、查找和统计 + +### 11.1 使用 `in` + +```python +contains_fastapi = "FastAPI" in agent_tools +``` + +### 11.2 `index()` 查找位置 + +```python +if "FastAPI" in agent_tools: + fastapi_index = agent_tools.index("FastAPI") +``` + +找不到时,`index()` 会产生 `ValueError`,因此可以先使用 `in`。 + +### 11.3 `count()` 统计次数 + +```python +python_count = agent_tools.count("Python") +``` + +找不到时返回 `0`,不会报错。 + +## 十二、排序和反转 + +### 12.1 `sort()` 修改原列表 + +```python +scores = [80, 95, 70, 88] +scores.sort() +print(scores) +``` + +默认从小到大排序。 + +降序排列: + +```python +scores.sort(reverse=True) +``` + +英文字符串通常按照字符编码顺序排序,大小写可能影响结果。 + +### 12.2 `reverse()` 反转当前顺序 + +```python +agent_tools.reverse() +``` + +`reverse()` 只把当前顺序倒过来,并不按大小重新排序。 + +### 12.3 `sorted()` 返回新列表 + +```python +original_scores = [80, 95, 70] +sorted_scores = sorted(original_scores) +``` + +`sorted()` 返回排序后的新列表,原列表保持不变。 + +## 十三、遍历列表 + +### 13.1 直接遍历元素 + +```python +for tool in agent_tools: + print(tool) +``` + +只需要元素时,优先直接遍历,代码最清晰。 + +### 13.2 需要索引时使用 `range(len(...))` + +```python +for index in range(len(agent_tools)): + print(f"{index + 1}. {agent_tools[index]}") +``` + +只有确实需要修改指定位置或使用索引时,才采用这种方式。 + +### 13.3 使用 `enumerate()` 同时取得编号和元素 + +```python +for number, tool in enumerate(agent_tools, start=1): + print(f"{number}. {tool}") +``` + +`enumerate()` 会同时提供编号和元素,通常比 `range(len(...))` 更易读。 + +本课先学会模仿这种常用写法,函数返回多个数据的原理会在后续课程继续讲解。 + +## 十四、简单二维列表 + +列表中的元素也可以是列表: + +```python +tool_records = [ + ["Python", "基础编程"], + ["FastAPI", "接口开发"], + ["Django", "Web 应用"], +] +``` + +读取 FastAPI 的用途: + +```python +print(tool_records[1][1]) +``` + +第一个索引选择第二条记录,第二个索引选择该记录中的第二个元素。 + +二维列表适合简单表格数据,但真实业务数据常使用字典、对象或数据库表达,将在后续课程学习。 + +## 十五、直接赋值与复制 + +### 15.1 直接赋值不会创建独立列表 + +```python +original_tools = ["Python", "FastAPI"] +backup_tools = original_tools + +backup_tools.append("Django") + +print(original_tools) +print(backup_tools) +``` + +两个变量都会看到 `Django`,因为它们指向同一个列表对象。 + +### 15.2 使用 `copy()` 创建浅复制 + +```python +original_tools = ["Python", "FastAPI"] +backup_tools = original_tools.copy() + +backup_tools.append("Django") +``` + +对于本课这种只包含字符串的简单列表,修改副本不会影响原列表。 + +`copy()` 创建的是浅复制(Shallow Copy)。嵌套列表中的共享问题属于进阶内容,本课暂不展开。 + +## 十六、方法返回值的常见误区 + +下面写法是错误思路: + +```python +agent_tools = ["Python", "FastAPI"] +result = agent_tools.append("Django") +print(result) +``` + +输出为 `None`。`append()`、`sort()`、`reverse()` 等方法直接修改原列表,通常不返回修改后的列表。 + +正确观察方式: + +```python +agent_tools.append("Django") +print(agent_tools) +``` + +## 十七、运行本课示例 + +在 PowerShell 中执行: + +```powershell +cd D:\Code\Python\01_python基础\1_8_列表 +python lists.py +``` + +示例无需用户输入,会依次展示创建、读取、修改、增删、查询、排序、遍历、二维列表和复制行为。 + +## 十八、常见错误 + +### 18.1 索引越界 + +访问不存在的位置会产生 `IndexError`。访问首尾元素前应确认列表非空。 + +### 18.2 删除不存在的元素 + +`remove()` 删除不存在的值会产生 `ValueError`,可以先使用 `in` 判断。 + +### 18.3 混淆 `append()` 与 `extend()` + +- `append()` 添加一个元素; +- `extend()` 依次添加多个元素。 + +### 18.4 把排序结果赋值回列表 + +```python +agent_tools = agent_tools.sort() +``` + +这会让 `agent_tools` 变成 `None`。应先调用,再读取原列表。 + +### 18.5 直接赋值误以为完成复制 + +`backup = original` 只是增加另一个变量名,并未创建独立列表。 + +## 十九、课堂练习 + +打开 `practice.py`,完成“Agent 工具清单管理器”。 + +运行命令: + +```powershell +python practice.py +``` + +练习会要求你完成列表的创建、修改、添加、删除、查询、排序、遍历和复制。 + +## 二十、思考题 + +1. 列表和字符串在可变性方面有什么区别? +2. `append()` 与 `extend()` 有什么区别? +3. `remove()` 与 `pop()` 有什么区别? +4. `sort()` 与 `sorted()` 对原列表的影响有什么不同? +5. 为什么访问列表首项前要检查列表是否为空? +6. 为什么 `backup = original` 不能得到独立副本? +7. 只需要元素时,为什么优先直接遍历列表? + +## 二十一、本课小结 + +- 列表可以保存多个有顺序的数据; +- 列表索引从 `0` 开始,也支持负索引和切片; +- 列表是可变对象,可以直接修改元素; +- `append()`、`insert()`、`extend()` 用于添加; +- `remove()`、`pop()`、`del`、`clear()` 用于删除; +- `index()` 和 `count()` 用于查找统计; +- `sort()` 修改原列表,`sorted()` 返回新列表; +- `for` 和 `enumerate()` 可以遍历列表; +- 直接赋值不会创建独立副本,简单列表可使用 `copy()`。 + +## 二十二、验收标准 + +- [ ] 能创建列表和空列表; +- [ ] 能使用索引和切片读取列表; +- [ ] 能修改、添加和删除元素; +- [ ] 能安全查找指定元素; +- [ ] 能排序并遍历列表; +- [ ] 能解释列表可变性; +- [ ] 能区分直接赋值与 `copy()`; +- [ ] 能完成并运行 `practice.py`; +- [ ] 能回答七道思考题。 diff --git a/01_python基础/1_8_列表/lists.py b/01_python基础/1_8_列表/lists.py new file mode 100644 index 0000000..1d939c5 --- /dev/null +++ b/01_python基础/1_8_列表/lists.py @@ -0,0 +1,100 @@ +# 第 1-8 课示例:列表 +# +# 本文件使用 Agent 开发工具作为统一示例,演示列表的主要操作。 +# 示例无需用户输入,可以直接运行并对照注释观察结果。 + + +# 一、创建列表并读取元素 +agent_tools = ["Python", "FastAPI", "Django"] +print(f"完整工具列表:{agent_tools}") +print(f"工具数量:{len(agent_tools)}") +print(f"第一个工具:{agent_tools[0]}") +print(f"最后一个工具:{agent_tools[-1]}") + + +# 二、切片返回一个新列表 +backend_tools = agent_tools[1:] +print(f"后端框架切片:{backend_tools}") + + +# 三、修改指定位置的元素 +# 列表是可变对象,可以直接修改已有索引对应的元素。 +agent_tools[2] = "Pydantic" +print(f"修改后的列表:{agent_tools}") + + +# 四、添加元素 +agent_tools.append("Django") +agent_tools.insert(1, "Git") +agent_tools.extend(["LangChain", "OpenAI SDK"]) +print(f"添加后的列表:{agent_tools}") + + +# 五、删除元素 +# remove() 按内容删除;pop() 按位置删除并返回被删除的数据。 +if "Git" in agent_tools: + agent_tools.remove("Git") + +removed_tool = agent_tools.pop() +print(f"pop() 删除的工具:{removed_tool}") +print(f"删除后的列表:{agent_tools}") + + +# 六、查找和统计 +contains_fastapi = "FastAPI" in agent_tools +fastapi_index = agent_tools.index("FastAPI") +python_count = agent_tools.count("Python") + +print(f"是否包含 FastAPI:{contains_fastapi}") +print(f"FastAPI 的索引:{fastapi_index}") +print(f"Python 出现次数:{python_count}") + + +# 七、排序和反转 +# sorted() 返回新列表,不改变原列表。 +sorted_tools = sorted(agent_tools) +print(f"原列表:{agent_tools}") +print(f"排序后的新列表:{sorted_tools}") + +# reverse() 直接修改当前列表顺序。 +agent_tools.reverse() +print(f"反转后的原列表:{agent_tools}") + + +# 八、直接遍历元素 +for tool in agent_tools: + print(f"正在学习:{tool}") + + +# 九、使用 enumerate() 同时取得编号和元素 +for number, tool in enumerate(agent_tools, start=1): + print(f"{number}. {tool}") + + +# 十、简单二维列表 +# 每条内部列表保存工具名称和用途。 +tool_records = [ + ["Python", "基础编程"], + ["FastAPI", "接口开发"], + ["Django", "Web 应用"], +] + +for record in tool_records: + print(f"工具:{record[0]},用途:{record[1]}") + + +# 十一、直接赋值与复制 +# alias_tools 和 original_tools 指向同一个列表。 +original_tools = ["Python", "FastAPI"] +alias_tools = original_tools +alias_tools.append("Django") + +print(f"直接赋值后的原列表:{original_tools}") +print(f"直接赋值后的别名列表:{alias_tools}") + +# copy() 为简单列表创建独立副本。 +copied_tools = original_tools.copy() +copied_tools.append("LangChain") + +print(f"复制后保持不变的原列表:{original_tools}") +print(f"修改后的副本:{copied_tools}") diff --git a/01_python基础/1_8_列表/practice.py b/01_python基础/1_8_列表/practice.py new file mode 100644 index 0000000..fa39b00 --- /dev/null +++ b/01_python基础/1_8_列表/practice.py @@ -0,0 +1,95 @@ +# 第 1-8 课课堂练习:Agent 工具清单管理器 +# +# 完成要求: +# 1. 根据注释完成列表的创建、修改、添加、删除、查询、排序和复制。 +# 2. 使用有意义的英文蛇形变量名。 +# 3. 调用 remove() 或 index() 前先判断元素是否存在。 +# 4. 不要删除题目注释。 +# 5. 完成后运行本文件并核对预期结果。 + + +# 练习一:创建列表 agent_tools,初始元素依次为: +# "Python"、"FastAPI"、"Django"。 + + +# 练习二:输出以下信息: +# 1. 完整列表; +# 2. 元素数量; +# 3. 第一个元素; +# 4. 最后一个元素。 +# 访问首尾元素前,先使用 if 判断 agent_tools 是否非空。 + + +# 练习三:使用 append() 在末尾添加 "LangChain"。 +# 再使用 insert() 在索引 1 的位置插入 "Git"。 + + +# 练习四:使用 extend() 一次添加两个工具: +# "Pydantic" 和 "OpenAI SDK"。 + + +# 练习五:把原列表中的 "Django" 修改为 "Django REST Framework"。 +# 提示:先使用 in 判断是否存在,再使用 index() 得到位置,最后按索引修改。 + +# 练习六:删除工具 "Git"。 +# 先使用 in 判断,存在时再调用 remove()。 + + +# 练习七:使用 pop() 删除列表最后一个元素。 +# 将被删除的工具保存到 removed_tool,并输出该变量。 + + +# 练习八:完成以下查询: +# 1. 判断是否包含 "FastAPI",保存到 contains_fastapi; +# 2. 统计 "Python" 出现次数,保存到 python_count; +# 3. 如果包含 "FastAPI",获取其索引并保存到 fastapi_index; +# 4. 如果不包含 "FastAPI",让 fastapi_index 保存 -1。 + +# 练习九:使用 sort() 对 agent_tools 原地排序。 +# 输出排序后的列表。 + + +# 练习十:使用 enumerate(agent_tools, start=1) 遍历工具列表。 +# 按照“1. FastAPI”这样的格式输出编号和工具名称。 + + +# 练习十一:创建独立副本 backup_tools。 +# 使用 copy() 复制 agent_tools,再向 backup_tools 添加 "Docker"。 +# 分别输出 agent_tools 和 backup_tools,确认原列表没有新增 Docker。 + + +# 练习十二:创建一个简单二维列表 tool_records: +# 第一条记录:["Python", "基础编程"] +# 第二条记录:["FastAPI", "接口开发"] +# 第三条记录:["Django", "Web 应用"] +# 使用 for 遍历,输出每个工具的名称和用途。 + + +# 练习十三:使用字符串乘法输出 30 个等号,再输出最终管理报告: +# 1. 最终 agent_tools; +# 2. 工具数量; +# 3. contains_fastapi; +# 4. fastapi_index; +# 5. python_count; +# 6. removed_tool; +# 7. backup_tools。 +# 预期操作过程: +# 初始列表:Python、FastAPI、Django +# 添加 LangChain +# 在索引 1 插入 Git +# 添加 Pydantic 和 OpenAI SDK +# 将 Django 修改为 Django REST Framework +# 删除 Git +# pop() 删除最后一个 OpenAI SDK +# 对剩余工具排序 +# 复制后只在副本中添加 Docker + + +# 完成后进行自查: +# 1. append()、insert() 和 extend() 是否按要求使用; +# 2. remove() 和 index() 前是否判断元素存在; +# 3. pop() 返回值是否保存到 removed_tool; +# 4. sort() 后列表是否按默认顺序排列; +# 5. enumerate() 的编号是否从 1 开始; +# 6. 修改 backup_tools 是否没有影响 agent_tools; +# 7. 二维列表是否能正确输出工具名称和用途。 diff --git a/AGENTS.md b/AGENTS.md index d4cedff..2c2f98a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,6 +68,9 @@ 5. 不得擅自删除、覆盖学习者已有的练习代码。 6. 如果学习者的代码存在问题,应先解释原因,再提出修改方案。 7. 删除文件、覆盖学习者已有内容、大范围重构或执行其他可能难以恢复的操作前,仍须先说明影响并取得学习者确认。 +8. 课程文档和代码默认只写入本地工作区,不自动执行 Git 暂存或提交。 +9. 只有学习者明确说“提交”时,才能执行 `git add` 和本地 `git commit`。 +10. 本项目只创建本地提交,不执行 `git push`,除非学习者以后重新明确授权推送。 ## 七、目录规划规范 diff --git a/README.md b/README.md index 335094d..632ae53 100644 --- a/README.md +++ b/README.md @@ -189,11 +189,11 @@ Python/ ## 当前学习进度 - 当前阶段:第一阶段——Python 基础语法。 -- 当前课程:`1_7_字符串`。 -- 当前状态:第七课学习中。 -- 已完成课程:`1_1_hello_world` 至 `1_6_循环`。 -- 已创建课程目录:`01_python基础/1_1_hello_world/` 至 `01_python基础/1_7_字符串/`。 -- 下一步:阅读第七课讲义、运行字符串示例并完成课堂练习。 +- 当前课程:`1_8_列表`。 +- 当前状态:第八课学习中。 +- 已完成课程:`1_1_hello_world` 至 `1_7_字符串`。 +- 已创建课程目录:`01_python基础/1_1_hello_world/` 至 `01_python基础/1_8_列表/`。 +- 下一步:阅读第八课讲义、运行列表示例并完成课堂练习。 ## 建议环境 diff --git a/docs/superpowers/specs/2026-07-27-第八课列表-design.md b/docs/superpowers/specs/2026-07-27-第八课列表-design.md new file mode 100644 index 0000000..929abb7 --- /dev/null +++ b/docs/superpowers/specs/2026-07-27-第八课列表-design.md @@ -0,0 +1,117 @@ +# 第八课“列表”教学设计 + +## 一、设计目标 + +第八课面向已经掌握字符串、条件判断和循环的零基础学习者,目标是让学习者理解“一个变量保存多个有序数据”的需求,并能够使用列表完成基础数据管理。 + +本课只讲列表,不讲元组。元组调整为独立的第九课。列表推导式保留到 Python 进阶阶段,避免本课知识密度过高。 + +## 二、课程目录 + +```text +01_python基础/1_8_列表/ +├── README.md +├── lists.py +└── practice.py +``` + +- `README.md`:中文讲义、运行方法、常见错误、练习说明和验收标准。 +- `lists.py`:带有详细中文注释的可运行示例。 +- `practice.py`:只包含题目和提示,不预填答案。 + +## 三、知识范围 + +本课覆盖: + +1. 创建列表和空列表; +2. 列表索引、负索引与切片; +3. 使用 `len()` 获取元素数量; +4. 修改指定位置的元素; +5. 使用 `append()`、`insert()` 添加元素; +6. 使用 `remove()`、`pop()` 和 `del` 删除元素; +7. 使用 `in` 判断成员; +8. 使用 `index()`、`count()` 查找和统计; +9. 使用 `sort()`、`reverse()` 排序和反转; +10. 使用 `for` 遍历列表; +11. 使用 `range(len(...))` 在确实需要索引时遍历; +12. 简单认识二维列表; +13. 理解列表可变性; +14. 区分直接赋值与浅复制列表的基础行为。 + +本课不覆盖: + +- 元组; +- 列表推导式; +- 深复制; +- 复杂排序键; +- 列表内部实现与性能分析。 + +## 四、教学顺序 + +课程按照“读取 → 修改 → 增删 → 查询 → 排序 → 遍历 → 复制”的顺序推进。 + +先使用字符串索引和切片作为已有知识连接点,再说明字符串不可变而列表可变。随后通过 Agent 工具名称列表演示列表的常见操作,最后介绍直接赋值导致两个变量引用同一个列表的现象。 + +## 五、示例程序 + +`lists.py` 使用 Agent 开发工具清单作为统一业务背景,依次演示: + +- 读取第一个和最后一个工具; +- 取得列表切片; +- 修改工具名称; +- 添加和删除工具; +- 查询某工具是否存在; +- 排序并遍历工具; +- 使用二维列表表示工具名称与用途; +- 对比直接赋值和 `copy()` 的结果。 + +示例不要求用户输入,确保可以直接运行并稳定复现结果。 + +## 六、课堂练习 + +`practice.py` 的项目名称为“Agent 工具清单管理器”。 + +练习要求学习者: + +1. 创建初始工具列表; +2. 输出长度、首项和末项; +3. 添加两个工具; +4. 在指定位置插入工具; +5. 修改一个元素; +6. 判断并删除指定工具; +7. 使用 `pop()` 取得被删除的数据; +8. 对列表排序; +9. 遍历并输出编号; +10. 统计指定工具出现次数; +11. 创建列表副本并验证修改副本不影响原列表; +12. 输出最终管理报告。 + +练习文件只提供中文注释、测试数据和预期核心结果,不包含参考答案。 + +## 七、错误处理边界 + +本课在调用 `remove()` 和 `index()` 前先使用 `in` 判断,避免因元素不存在产生 `ValueError`。 + +访问首尾元素前应确认列表非空。复杂异常处理将在后续课程讲解,本课使用条件判断保护常见边界。 + +## 八、验证方式 + +创建课程后执行: + +```powershell +python lists.py +python practice.py +``` + +验收要求: + +- `lists.py` 正常退出且输出覆盖所有主要列表操作; +- 空白 `practice.py` 可以正常执行; +- `practice.py` 不包含非注释答案; +- 根目录 `README.md` 的当前课程更新为 `1_8_列表`; +- 不创建 `1_9_元组` 目录; +- 不修改第六、七课文件。 + +## 九、后续课程调整 + +第九课单独讲解元组,重点包括创建、单元素元组、索引切片、不可变性、解包和适用场景。字典、集合及后续课程编号依次顺延,实际目录仍按照学习进度逐课创建。