From 96e4b696e0c4086541fcc9d605dfa4497729046e Mon Sep 17 00:00:00 2001 From: "zhiye.sun" Date: Mon, 27 Jul 2026 13:38:25 +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=BE=AA=E7=8E=AF=E4=B8=8E=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?=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_6_循环/README.md | 488 ++++++++++++++++++++ 01_python基础/1_6_循环/loops.py | 103 +++++ 01_python基础/1_6_循环/practice.py | 96 ++++ 01_python基础/1_7_字符串/README.md | 637 +++++++++++++++++++++++++++ 01_python基础/1_7_字符串/practice.py | 101 +++++ 01_python基础/1_7_字符串/strings.py | 105 +++++ README.md | 10 +- 7 files changed, 1535 insertions(+), 5 deletions(-) create mode 100644 01_python基础/1_6_循环/README.md create mode 100644 01_python基础/1_6_循环/loops.py create mode 100644 01_python基础/1_6_循环/practice.py create mode 100644 01_python基础/1_7_字符串/README.md create mode 100644 01_python基础/1_7_字符串/practice.py create mode 100644 01_python基础/1_7_字符串/strings.py diff --git a/01_python基础/1_6_循环/README.md b/01_python基础/1_6_循环/README.md new file mode 100644 index 0000000..c6067ba --- /dev/null +++ b/01_python基础/1_6_循环/README.md @@ -0,0 +1,488 @@ +# 第 1-6 课:循环 + +## 一、本课目标 + +完成本课后,你应该能够: + +1. 解释循环为什么能减少重复代码; +2. 使用 `for` 循环按照指定次数重复执行代码; +3. 使用 `range()` 生成整数序列; +4. 使用 `while` 在条件成立期间重复执行; +5. 使用计数器记录执行次数; +6. 使用累加器汇总一组数据; +7. 在循环中结合 `if` 进行判断; +8. 使用 `break` 提前结束循环; +9. 使用 `continue` 跳过本次循环; +10. 识别并避免常见的死循环。 + +## 二、前置知识 + +开始本课前,你应该已经掌握: + +- 变量与基础数据类型; +- 数字计算和比较运算; +- `if...elif...else` 条件判断; +- `input()` 和类型转换; +- 代码块需要使用四个空格缩进。 + +## 三、为什么需要循环 + +如果要输出五次学习提醒,可以重复写五行: + +```python +print("开始学习 Python") +print("开始学习 Python") +print("开始学习 Python") +print("开始学习 Python") +print("开始学习 Python") +``` + +这种写法存在明显问题: + +- 重复代码很多; +- 修改文字时要修改多个位置; +- 执行次数较大时无法手工编写; +- 容易漏写或写错。 + +循环(Loop)可以让一段代码重复执行: + +```python +for count in range(5): + print("开始学习 Python") +``` + +循环的核心思想是:让计算机负责重复,人只需要描述重复规则。 + +## 四、`for` 循环 + +`for` 循环适合处理“已经知道重复次数”或“依次处理一组数据”的场景。 + +基本结构: + +```python +for 循环变量 in 可迭代对象: + 重复执行的代码 +``` + +第一次接触“可迭代对象”时,可以先把它理解为能够依次提供数据的对象。字符串、列表和 `range()` 都可以依次提供数据。 + +示例: + +```python +for count in range(3): + print("正在进行 Agent 学习打卡") +``` + +输出三次相同内容。 + +每次循环时,`range(3)` 会依次提供一个整数,并临时保存到循环变量 `count` 中。 + +## 五、认识 `range()` + +`range()` 用于表示一个整数范围,经常与 `for` 配合。 + +### 5.1 `range(结束值)` + +```python +for number in range(5): + print(number) +``` + +输出: + +```text +0 +1 +2 +3 +4 +``` + +关键规则:从 `0` 开始,包含开始值,不包含结束值。 + +因此 `range(5)` 提供 5 个整数,但最后一个整数是 `4`。这种“不包含结束值”的规则在 Python 中非常常见。 + +### 5.2 `range(开始值, 结束值)` + +```python +for day in range(1, 6): + print(day) +``` + +输出 `1` 到 `5`。`6` 仍然不包含在范围中。 + +如果希望显示“第 1 次”到“第 5 次”,`range(1, 6)` 通常比 `range(5)` 更直观。 + +### 5.3 `range(开始值, 结束值, 步长)` + +步长表示每次增加多少: + +```python +for number in range(0, 11, 2): + print(number) +``` + +输出: + +```text +0 +2 +4 +6 +8 +10 +``` + +步长也可以是负数: + +```python +for number in range(5, 0, -1): + print(number) +``` + +输出从 `5` 到 `1`,可用于倒计时。 + +## 六、使用循环变量 + +循环变量会在每次循环时保存当前数据: + +```python +for day in range(1, 4): + print(f"第 {day} 天:完成 Python 学习") +``` + +输出: + +```text +第 1 天:完成 Python 学习 +第 2 天:完成 Python 学习 +第 3 天:完成 Python 学习 +``` + +循环变量应使用有意义的名称,例如 `day`、`task_number`,避免长期使用难以理解的 `a`、`x`。 + +## 七、遍历字符串 + +`for` 也能依次取得字符串中的每个字符: + +```python +for character in "Agent": + print(character) +``` + +输出: + +```text +A +g +e +n +t +``` + +这种“从头到尾依次取出数据”的操作称为遍历(Traversal)。以后学习列表、字典和文件时,会经常使用遍历。 + +## 八、计数器 + +计数器(Counter)是用来记录次数的变量。 + +```python +completed_count = 0 + +for task_number in range(1, 6): + completed_count += 1 + +print(f"已完成 {completed_count} 个任务") +``` + +执行过程: + +1. 循环前把计数器初始化为 `0`; +2. 每次循环执行 `completed_count += 1`; +3. 循环五次后,计数器变为 `5`。 + +初始化必须写在循环外。如果写在循环内,每次都会重新变回 `0`。 + +## 九、累加器 + +累加器(Accumulator)用于把多次产生的数值汇总起来。 + +```python +total_hours = 0.0 + +for day in range(1, 6): + daily_hours = float(input(f"请输入第 {day} 天的学习小时数:")) + total_hours += daily_hours + +print(f"总学习时间:{total_hours} 小时") +``` + +`total_hours` 的变化过程可能是: + +```text +初始值:0.0 +第 1 天后:2.0 +第 2 天后:3.5 +第 3 天后:6.0 +``` + +计数器通常每次增加固定值;累加器通常加入每次得到的实际数据。 + +## 十、循环与条件判断结合 + +循环中可以使用 `if`: + +```python +passed_count = 0 + +for score in range(55, 101, 15): + if score >= 60: + passed_count += 1 + print(f"{score} 分:通过") + else: + print(f"{score} 分:未通过") + +print(f"通过数量:{passed_count}") +``` + +注意缩进层级: + +- `for` 内部缩进一级; +- `if` 内部再缩进一级; +- 回到循环外时取消全部循环缩进。 + +## 十一、`while` 循环 + +`while` 的中文含义是“当……时”。只要条件为 `True`,循环就会继续。 + +基本结构: + +```python +while 条件: + 重复执行的代码 +``` + +示例: + +```python +current_day = 1 + +while current_day <= 3: + print(f"完成第 {current_day} 天学习") + current_day += 1 +``` + +执行过程: + +1. `current_day` 初始为 `1`; +2. 判断 `current_day <= 3`,成立则执行循环; +3. 输出后把 `current_day` 增加 `1`; +4. 回到条件处重新判断; +5. 当 `current_day` 变为 `4` 时,条件为 `False`,循环结束。 + +## 十二、`for` 和 `while` 如何选择 + +通常可以这样判断: + +- 已知需要重复多少次:优先考虑 `for`; +- 不知道次数,只知道结束条件:优先考虑 `while`。 + +示例场景: + +```text +依次处理 7 天学习记录 → for +重复询问密码直到输入正确 → while +输出 1 到 100 → for +余额大于 0 时继续扣费 → while +``` + +两者有时可以互相改写,但应选择更能表达业务意图的方式。 + +## 十三、避免死循环 + +死循环(Infinite Loop)是无法自然结束的循环。 + +错误示例: + +```text +current_day = 1 + +while current_day <= 3: + print(current_day) +``` + +循环中没有修改 `current_day`,条件会一直为 `True`,程序不断输出 `1`。 + +编写 `while` 时必须检查: + +1. 条件中的变量是否会发生变化; +2. 变化方向是否会逐渐接近结束条件; +3. 是否存在明确的退出方式。 + +如果程序意外进入死循环,可以在终端中按 `Ctrl + C` 尝试停止。 + +## 十四、使用 `break` 提前结束循环 + +`break` 表示立即结束当前循环: + +```python +while True: + command = input("请输入命令,输入 exit 结束:") + + if command == "exit": + break + + print(f"正在处理命令:{command}") + +print("程序已结束") +``` + +`while True` 本身会无限循环,但遇到 `break` 后可以退出。只有存在清晰退出条件时,才应使用这种结构。 + +`break` 只结束它所在的最近一层循环,不会直接结束整个 Python 程序。 + +## 十五、使用 `continue` 跳过本次循环 + +`continue` 表示跳过本次循环剩余代码,直接开始下一次循环: + +```python +for day in range(1, 6): + if day == 3: + continue + + print(f"记录第 {day} 天学习数据") +``` + +第 3 天不会输出,其他天正常输出。 + +可以把两者简单区分为: + +- `break`:整个循环到此结束; +- `continue`:只跳过当前这一次,循环还会继续。 + +## 十六、嵌套循环初步认识 + +循环内部还可以包含循环: + +```python +for week in range(1, 3): + for day in range(1, 4): + print(f"第 {week} 周,第 {day} 天") +``` + +外层循环每执行一次,内层循环都会完整执行三次,因此一共输出 `2 × 3 = 6` 行。 + +嵌套循环容易增加理解和运行成本。本课只要求看懂简单结构,练习不强制使用。 + +## 十七、运行本课示例 + +在 PowerShell 中执行: + +```powershell +cd D:\Code\Python\01_python基础\1_6_循环 +python loops.py +``` + +示例会演示: + +- `range()` 的三种常见形式; +- 计数和累加; +- 循环结合条件判断; +- `while` 的变量更新; +- `break` 和 `continue`。 + +示例不需要用户输入,可以直接运行并对照注释观察结果。 + +## 十八、常见错误 + +### 18.1 忘记冒号 + +`for` 和 `while` 行末都必须使用英文冒号 `:`。 + +### 18.2 循环体没有缩进 + +属于循环的代码必须统一缩进四个空格。 + +### 18.3 `range()` 结束值理解错误 + +`range(1, 5)` 提供 `1、2、3、4`,不包含 `5`。 + +### 18.4 把计数器初始化写在循环内 + +这样每次循环都会重置,无法正确累计。 + +### 18.5 `while` 忘记更新条件变量 + +这很可能造成死循环。 + +### 18.6 混淆 `break` 与 `continue` + +`break` 结束循环,`continue` 只跳过当前一次。 + +### 18.7 循环变量命名没有含义 + +优先使用 `day`、`task_number` 等名称,帮助读者理解当前遍历的数据。 + +## 十九、课堂练习 + +打开 `practice.py`,完成“Agent 学习打卡统计器”。程序需要收集连续多天的学习时长,统计总时长、有效学习天数和达标情况。 + +运行命令: + +```powershell +python practice.py +``` + +建议先使用以下数据测试: + +```text +计划打卡天数:5 +第 1 天:2 +第 2 天:0 +第 3 天:1.5 +第 4 天:-1 +第 5 天:3 +``` + +约定: + +- `-1` 表示本次数据无效,使用 `continue` 跳过; +- `0` 是有效记录,但不算完成学习; +- 大于 `0` 算一个有效学习日; +- 累计学习时长达到 `5` 小时视为总目标达标。 + +使用上述数据时,预期总时长为 `6.5` 小时,有效学习日为 `3` 天,无效记录为 `1` 条,总目标达标。 + +## 二十、思考题 + +1. `range(5)` 会提供哪些整数? +2. 为什么 `range(1, 6)` 可以表示第 1 到第 5 次? +3. 计数器与累加器有什么区别? +4. 哪些场景更适合使用 `while`? +5. `break` 和 `continue` 有什么区别? +6. `while` 循环为什么容易出现死循环? +7. 循环中的 `if` 为什么通常会比循环多一级缩进? + +## 二十一、本课小结 + +- 循环用于重复执行代码; +- `for` 适合已知次数或依次处理数据的场景; +- `range()` 包含开始值,不包含结束值; +- 计数器记录次数,累加器汇总数值; +- `while` 在条件为真时持续执行; +- `while` 中必须确保条件最终能够变为假; +- `break` 提前结束循环; +- `continue` 跳过当前一次循环; +- 循环可以与条件判断结合,实现更真实的业务逻辑。 + +## 二十二、验收标准 + +- [ ] 能使用 `for` 和 `range()` 重复执行代码; +- [ ] 能解释 `range()` 为什么不包含结束值; +- [ ] 能使用计数器和累加器; +- [ ] 能在循环中使用条件判断; +- [ ] 能编写可以正常结束的 `while` 循环; +- [ ] 能区分 `break` 和 `continue`; +- [ ] 能完成并运行 `practice.py`; +- [ ] 能使用建议数据得到正确统计结果; +- [ ] 能回答七道思考题。 diff --git a/01_python基础/1_6_循环/loops.py b/01_python基础/1_6_循环/loops.py new file mode 100644 index 0000000..99a4a51 --- /dev/null +++ b/01_python基础/1_6_循环/loops.py @@ -0,0 +1,103 @@ +# 第 1-6 课示例:循环 +# +# 本文件依次演示 for、range()、计数器、累加器、while、break 和 continue。 +# 每段示例都会直接运行,不要求用户输入,便于重复观察结果。 + + +# 一、使用 range(结束值) +# range(3) 依次提供 0、1、2,不包含结束值 3。 +for number in range(3): + print(f"range(3) 当前数字:{number}") + + +# 二、指定开始值和结束值 +# range(1, 4) 依次提供 1、2、3,适合显示自然的次数编号。 +for day in range(1, 4): + print(f"第 {day} 天:完成 Python 学习") + + +# 三、指定步长 +# 从 0 开始,每次增加 2,在到达 11 前结束。 +for even_number in range(0, 11, 2): + print(f"当前偶数:{even_number}") + + +# 四、遍历字符串 +# for 会依次取得字符串中的每一个字符。 +for character in "Agent": + print(f"当前字符:{character}") + + +# 五、使用计数器 +# 计数器必须在循环外初始化,否则每次循环都会重新变为 0。 +completed_count = 0 + +for task_number in range(1, 6): + completed_count += 1 + print(f"完成第 {task_number} 个任务") + +print(f"任务完成总数:{completed_count}") + + +# 六、使用累加器 +# daily_hours 表示五天的学习时长。 +# 列表会在后续课程详细讲解,本例只需知道 for 能依次取得其中的数字。 +daily_hours = [2.0, 1.5, 0.0, 2.5, 3.0] +total_hours = 0.0 + +for hours in daily_hours: + total_hours += hours + +print(f"五天总学习时长:{total_hours} 小时") + + +# 七、循环结合条件判断 +# 只有学习时长大于 0 的记录才算有效学习日。 +effective_days = 0 + +for hours in daily_hours: + if hours > 0: + effective_days += 1 + +print(f"有效学习日:{effective_days} 天") + + +# 八、while 循环 +# 每次循环末尾增加 current_day,确保条件最终会变为 False。 +current_day = 1 + +while current_day <= 3: + print(f"while 正在处理第 {current_day} 天") + current_day += 1 + + +# 九、使用 continue 跳过无效数据 +# -1 表示无效记录;遇到它时跳过本次循环的剩余代码。 +learning_records = [2.0, -1.0, 1.5, 0.0] +valid_total_hours = 0.0 + +for hours in learning_records: + if hours == -1: + print("发现无效记录,本次跳过") + continue + + valid_total_hours += hours + +print(f"排除无效记录后的总时长:{valid_total_hours} 小时") + + +# 十、使用 break 提前结束循环 +# 当 task_number 等于 4 时结束循环,因此不会处理第 4、5 个任务。 +for task_number in range(1, 6): + if task_number == 4: + print("收到停止信号,提前结束任务循环") + break + + print(f"正在处理第 {task_number} 个任务") + + +# 十一、简单嵌套循环 +# 外层循环执行两次;每次都会让内层循环完整执行三次。 +for week in range(1, 3): + for day in range(1, 4): + print(f"第 {week} 周,第 {day} 天") diff --git a/01_python基础/1_6_循环/practice.py b/01_python基础/1_6_循环/practice.py new file mode 100644 index 0000000..2491c66 --- /dev/null +++ b/01_python基础/1_6_循环/practice.py @@ -0,0 +1,96 @@ +# 第 1-6 课课堂练习:Agent 学习打卡统计器 +# +# 完成要求: +# 1. 根据注释使用 for、range()、if、continue、计数器和累加器。 +# 2. 输入内容需要转换为正确的数字类型。 +# 3. 使用有意义的英文蛇形变量名。 +# 4. 注意冒号和四个空格缩进。 +# 5. 不要删除题目注释。 +# 6. 完成后使用题目提供的数据检查结果。 + + +# 练习一:接收计划打卡天数。 +# 使用 int() 转换,并保存到 planned_days。 + +# 练习二:在循环开始前创建三个统计变量: +# 1. total_hours:总学习时长,初始值为 0.0; +# 2. effective_days:有效学习日数量,初始值为 0; +# 3. invalid_records:无效记录数量,初始值为 0。 + +# 练习三:使用 for 和 range() 循环 planned_days 次。 +# 建议让循环变量 day 从 1 开始,这样提示语可以直接显示“第几天”。 +# 注意:range() 的结束值不包含在结果中,需要自行计算正确结束值。 + +# 练习四:在循环中接收当天学习小时数。 +# 提示语应包含当前 day,例如“请输入第 1 天的学习小时数”。 +# 使用 float() 转换,并保存到 daily_hours。 + +# 练习五:在循环中判断 daily_hours 是否等于 -1。 +# 如果等于 -1: +# 1. invalid_records 增加 1; +# 2. 输出“本条记录无效,已跳过”; +# 3. 使用 continue 跳过本次循环剩余代码。 + + +# 练习六:对于没有被 continue 跳过的有效记录: +# 1. 把 daily_hours 累加到 total_hours; +# 2. 如果 daily_hours 大于 0,让 effective_days 增加 1; +# 3. 如果 daily_hours 等于 0,输出“今天没有完成学习”。 + +# 练习七:循环结束后,判断总目标是否达标。 +# total_hours 大于或等于 5 时,target_reached 为 True,否则为 False。 +# 请直接使用比较运算生成布尔值,不必使用 if 分别赋值。 + +# 练习八:使用字符串乘法输出 30 个等号,再使用 f-string 输出统计报告: +# 1. 计划打卡天数 planned_days; +# 2. 总学习时长 total_hours; +# 3. 有效学习日 effective_days; +# 4. 无效记录 invalid_records; +# 5. 总目标是否达标 target_reached。 + +# 练习九:使用 if...else 输出最终建议: +# - target_reached 为 True:输出“学习总时长已达标,请保持节奏。” +# - target_reached 为 False:输出“学习总时长尚未达标,请继续努力。” + +# 练习十:额外完成一个独立的 while 循环。 +# 1. 创建 review_count,初始值为 1; +# 2. 当 review_count 小于或等于 3 时,输出“正在进行第几次复习”; +# 3. 每次循环末尾让 review_count 增加 1; +# 4. 确保循环能够正常结束。 + +# 第一次运行请使用以下数据: +# 计划打卡天数:5 +# 第 1 天:2 +# 第 2 天:0 +# 第 3 天:1.5 +# 第 4 天:-1 +# 第 5 天:3 +# +# 预期结果: +# total_hours = 6.5 +# effective_days = 3 +# invalid_records = 1 +# target_reached = True +# while 循环依次输出第 1、2、3 次复习,然后正常结束。 + + +# 第二次运行可以测试未达标情况: +# 计划打卡天数:3 +# 第 1 天:1 +# 第 2 天:0 +# 第 3 天:2 +# +# 预期结果: +# total_hours = 3.0 +# effective_days = 2 +# invalid_records = 0 +# target_reached = False + + +# 完成后进行自查: +# 1. for 循环是否正好执行 planned_days 次; +# 2. -1 是否只增加无效记录,没有加入总时长; +# 3. 0 是否加入总时长,但没有增加有效学习日; +# 4. continue 是否位于无效数据分支中; +# 5. 统计变量是否都在循环外初始化; +# 6. while 循环是否能够在三次后正常结束。 diff --git a/01_python基础/1_7_字符串/README.md b/01_python基础/1_7_字符串/README.md new file mode 100644 index 0000000..12c3761 --- /dev/null +++ b/01_python基础/1_7_字符串/README.md @@ -0,0 +1,637 @@ +# 第 1-7 课:字符串 + +## 一、本课目标 + +完成本课后,你应该能够: + +1. 解释字符串是什么; +2. 使用索引读取字符串中的单个字符; +3. 使用切片取得字符串的一部分; +4. 使用 `len()` 获取字符串长度; +5. 使用 `for` 遍历字符串; +6. 使用常见字符串方法清理、转换和查找文本; +7. 使用 `in` 判断字符串是否包含指定内容; +8. 使用 `split()` 分割字符串,使用 `join()` 连接文本; +9. 理解字符串不可变的含义; +10. 编写一个简单的 Agent 提示词文本分析器。 + +## 二、前置知识 + +开始本课前,你应该已经掌握: + +- 创建字符串变量; +- 使用 `input()` 接收字符串; +- 使用 f-string 输出变量; +- 使用条件判断; +- 使用 `for` 循环遍历数据。 + +## 三、字符串是什么 + +字符串(String,类型名为 `str`)是一串按照顺序排列的字符。 + +```python +prompt = "请帮我分析这段代码" +``` + +这个字符串包含中文字符。字符串也可以包含: + +- 英文字母; +- 数字字符; +- 空格; +- 标点符号; +- 换行符等特殊字符。 + +只要内容被成对的单引号或双引号包围,Python 就会把它看作字符串: + +```python +name = "Bruce" +age_text = "18" +empty_text = "" +``` + +`age_text` 看起来像数字,但它的数据类型仍然是字符串。 + +## 四、字符串中的字符有位置 + +字符串中的每个字符都有编号,这个编号称为索引(Index)。 + +Python 的索引从 `0` 开始: + +```text +字符串: A g e n t +正索引: 0 1 2 3 4 +负索引:-5 -4 -3 -2 -1 +``` + +读取单个字符: + +```python +word = "Agent" + +print(word[0]) # A +print(word[1]) # g +print(word[-1]) # t +``` + +方括号 `[]` 用于指定索引。 + +### 4.1 负索引 + +负索引从字符串末尾开始: + +- `-1` 表示最后一个字符; +- `-2` 表示倒数第二个字符; +- 依此类推。 + +需要取得最后一个字符时,`word[-1]` 比先计算字符串长度更方便。 + +### 4.2 索引越界 + +`"Agent"` 只有 5 个字符,有效正索引是 `0` 到 `4`。 + +```text +word[5] +``` + +会产生 `IndexError`,中文可以理解为“索引超出有效范围”。 + +## 五、使用 `len()` 获取长度 + +`len()` 返回字符串包含的字符数量: + +```python +prompt = "Hello" +prompt_length = len(prompt) + +print(prompt_length) +``` + +输出为 `5`。 + +空格和标点也会占用字符位置: + +```python +print(len("A B")) # 结果为 3 +``` + +`len()` 常用于: + +- 检查用户输入是否过短或过长; +- 统计提示词长度; +- 判断字符串是否为空; +- 配合索引和循环处理文本。 + +## 六、字符串切片 + +切片(Slicing)用于取得字符串的一部分。 + +基本形式: + +```python +字符串[开始索引:结束索引] +``` + +切片包含开始索引,不包含结束索引: + +```python +word = "Python" + +print(word[0:3]) # Pyt +print(word[2:6]) # thon +``` + +这种规则与 `range()` 相似:包含开始,不包含结束。 + +### 6.1 省略开始或结束索引 + +```python +word = "Python" + +print(word[:3]) # 从开头到索引 3 之前:Pyt +print(word[3:]) # 从索引 3 到末尾:hon +print(word[:]) # 整个字符串:Python +``` + +### 6.2 使用负索引切片 + +```python +file_name = "report.txt" + +print(file_name[-3:]) # txt +``` + +### 6.3 指定步长 + +完整形式: + +```python +字符串[开始索引:结束索引:步长] +``` + +```python +word = "Python" + +print(word[::2]) # Pto +print(word[::-1]) # nohtyP +``` + +`[::-1]` 常用于反转字符串。现阶段理解其结果即可,不需要死记复杂切片组合。 + +### 6.4 切片通常不会越界报错 + +```python +word = "Agent" +print(word[0:100]) +``` + +结果仍然是 `Agent`。单个索引越界通常报错,而切片结束位置超过长度时会安全地取到末尾。 + +## 七、遍历字符串 + +字符串可以使用 `for` 逐个处理字符: + +```python +for character in "Agent": + print(character) +``` + +统计字母出现次数: + +```python +letter_count = 0 + +for character in "Agent application": + if character == "a": + letter_count += 1 + +print(letter_count) +``` + +需要注意英文大小写。`"A"` 和 `"a"` 是不同字符。 + +## 八、字符串方法是什么 + +方法(Method)是某种数据自身提供的操作。 + +字符串方法通常写成: + +```python +字符串.方法名() +``` + +例如: + +```python +user_input = " Python " +clean_text = user_input.strip() +``` + +点号 `.` 表示使用这个字符串提供的 `strip()` 方法。 + +方法与面向对象有关,将在后续阶段系统学习。本课先掌握常用字符串方法的用途。 + +## 九、清理字符串 + +### 9.1 `strip()` + +`strip()` 删除字符串开头和结尾的空白: + +```python +raw_text = " Python Agent " +clean_text = raw_text.strip() + +print(clean_text) +``` + +输出: + +```text +Python Agent +``` + +它不会删除字符串中间的正常空格。 + +### 9.2 `lstrip()` 与 `rstrip()` + +- `lstrip()`:只清理左侧; +- `rstrip()`:只清理右侧。 + +处理用户输入时,`strip()` 最常用。 + +## 十、转换英文字母大小写 + +```python +technology = "FastAPI" + +print(technology.lower()) # fastapi +print(technology.upper()) # FASTAPI +``` + +常见方法: + +- `lower()`:转成小写; +- `upper()`:转成大写; +- `title()`:让英文单词首字母大写; +- `capitalize()`:让字符串首字符大写,其余英文字符转为小写。 + +大小写转换常用于不区分大小写的输入判断: + +```python +answer = input("是否继续(yes/no):").strip().lower() + +if answer == "yes": + print("继续执行") +``` + +这样输入 `YES`、`Yes` 或两侧带空格时也能正确识别。 + +## 十一、替换文本 + +`replace()` 返回替换后的新字符串: + +```python +old_text = "我正在学习 Java" +new_text = old_text.replace("Java", "Python") + +print(new_text) +``` + +输出: + +```text +我正在学习 Python +``` + +原始变量 `old_text` 不会自动改变。 + +## 十二、查找和统计 + +### 12.1 使用 `in` + +`in` 判断某段内容是否包含在字符串中,结果是布尔值: + +```python +prompt = "请使用 Python 编写 Agent" + +contains_python = "Python" in prompt +print(contains_python) +``` + +### 12.2 `find()` + +`find()` 返回第一次出现的位置: + +```python +text = "Python Agent" + +print(text.find("Agent")) # 7 +print(text.find("Java")) # -1 +``` + +找不到时返回 `-1`。 + +### 12.3 `count()` + +`count()` 统计内容出现次数: + +```python +text = "Agent Agent Python" +print(text.count("Agent")) +``` + +输出为 `2`。 + +### 12.4 开头和结尾判断 + +```python +file_name = "agent.py" + +print(file_name.startswith("agent")) +print(file_name.endswith(".py")) +``` + +`startswith()` 和 `endswith()` 都返回布尔值。 + +## 十三、分割字符串 + +`split()` 按照指定分隔符拆分字符串: + +```python +technologies = "Python,FastAPI,Django" +technology_list = technologies.split(",") + +print(technology_list) +``` + +输出: + +```text +['Python', 'FastAPI', 'Django'] +``` + +这个结果是列表(List)。列表是可以保存多个数据的容器,将在下一课详细学习。本课只需要知道:`split()` 能把一段文本拆成多个部分。 + +如果不提供分隔符,`split()` 会按照连续空白进行分割: + +```python +words = "Python Agent 开发".split() +``` + +## 十四、连接多个字符串 + +`join()` 使用指定字符串连接多个文本: + +```python +technology_list = ["Python", "FastAPI", "Django"] +result = " -> ".join(technology_list) + +print(result) +``` + +输出: + +```text +Python -> FastAPI -> Django +``` + +可以这样理解:用 `" -> "` 把列表中的每个字符串连接起来。 + +被连接的数据必须是字符串。如果列表中包含整数,直接使用 `join()` 会报 `TypeError`。 + +## 十五、字符串判断方法 + +常见判断方法: + +| 方法 | 作用 | +| --- | --- | +| `isdigit()` | 是否全部由数字字符组成 | +| `isalpha()` | 是否全部由字母字符组成 | +| `isalnum()` | 是否全部由字母或数字字符组成 | +| `isspace()` | 是否全部由空白字符组成 | + +示例: + +```python +age_text = "18" + +if age_text.isdigit(): + age = int(age_text) + print(f"年龄:{age}") +else: + print("请输入整数数字") +``` + +`isdigit()` 能帮助我们在调用 `int()` 前检查简单的非负整数字符串,但它不能覆盖负数、小数等所有数字形式。 + +## 十六、字符串是不可变的 + +不可变(Immutable)表示字符串创建后,不能直接修改其中某个字符。 + +错误示例: + +```text +word = "Agent" +word[0] = "a" +``` + +这会产生 `TypeError`。 + +字符串方法通常返回一个新字符串: + +```python +original_text = " Python " +clean_text = original_text.strip() + +print(original_text) +print(clean_text) +``` + +如果希望变量以后使用处理后的结果,需要重新赋值: + +```python +text = text.strip().lower() +``` + +## 十七、转义字符 + +反斜杠 `\` 可以与其他字符组成特殊含义: + +| 写法 | 作用 | +| --- | --- | +| `\n` | 换行 | +| `\t` | 制表符 | +| `\"` | 在双引号字符串中表示双引号 | +| `\\` | 表示一个反斜杠 | + +示例: + +```python +print("第一行\n第二行") +print("名称\t时长") +``` + +Windows 路径中包含反斜杠。可以使用原始字符串,在开头添加 `r`: + +```python +project_path = r"D:\Code\Python" +``` + +原始字符串会减少反斜杠被当作转义符解释的情况。 + +## 十八、多行字符串 + +三个双引号或三个单引号可以创建多行字符串: + +```python +report = """Agent 学习报告 +学习方向:Python +当前状态:进行中""" + +print(report) +``` + +多行字符串会保留代码中的换行。需要注意开头和结尾位置,避免无意中加入额外空行。 + +## 十九、f-string 格式控制 + +f-string 除了插入变量,还能简单控制数字格式: + +```python +total_hours = 6.5 +progress = 0.756 + +print(f"总时长:{total_hours:.2f} 小时") +print(f"完成率:{progress:.1%}") +``` + +输出: + +```text +总时长:6.50 小时 +完成率:75.6% +``` + +- `.2f`:浮点数保留两位小数; +- `.1%`:转为百分比并保留一位小数。 + +这是常用格式,现阶段能够模仿使用即可。 + +## 二十、方法链 + +多个字符串方法可以连续调用: + +```python +raw_answer = " YES " +clean_answer = raw_answer.strip().lower() + +print(clean_answer) +``` + +执行顺序从左到右: + +1. `strip()` 得到 `"YES"`; +2. `lower()` 得到 `"yes"`; +3. 最终结果保存到 `clean_answer`。 + +方法链不宜过长。处理步骤复杂时,可以使用多个含义清晰的中间变量。 + +## 二十一、运行本课示例 + +在 PowerShell 中执行: + +```powershell +cd D:\Code\Python\01_python基础\1_7_字符串 +python strings.py +``` + +示例无需用户输入,会依次展示索引、切片、遍历和常用字符串方法。 + +## 二十二、常见错误 + +### 22.1 索引从 1 开始计算 + +Python 字符串第一个字符的索引是 `0`,不是 `1`。 + +### 22.2 切片包含结束索引 + +切片不包含结束索引。`text[0:3]` 取得索引 `0、1、2`。 + +### 22.3 调用方法后忘记保存结果 + +```python +text = " Python " +text.strip() +print(text) +``` + +原变量仍然保留空格。应写成: + +```python +text = text.strip() +``` + +### 22.4 查找内容时忽略大小写 + +`"python" in "Python Agent"` 为 `False`。如果业务允许忽略大小写,可以先统一使用 `lower()`。 + +### 22.5 混淆 `split()` 和 `join()` + +- `split()`:一个字符串拆成多个部分; +- `join()`:多个字符串连接成一个字符串。 + +### 22.6 直接修改字符串字符 + +字符串不可变,不能执行 `text[0] = "A"`。 + +## 二十三、课堂练习 + +打开 `practice.py`,完成“Agent 提示词文本分析器”。程序需要清理用户输入,分析长度、关键词、单词数量和文件名,并生成格式化报告。 + +运行命令: + +```powershell +python practice.py +``` + +建议第一次输入: + +```text + 请使用 Python 帮我开发一个 Agent 应用 +``` + +预期能判断其中包含 `python` 和 `agent` 关键词。判断关键词时应忽略英文大小写。 + +## 二十四、思考题 + +1. `"Agent"[0]` 和 `"Agent"[-1]` 分别是什么? +2. 为什么 `text[0:3]` 不包含索引 `3`? +3. `strip()` 会不会删除字符串中间的空格? +4. `replace()` 会直接修改原字符串吗? +5. `split()` 和 `join()` 的方向有什么不同? +6. 为什么字符串方法的返回结果经常需要重新赋值? +7. 如何忽略大小写判断文本中是否包含 `python`? + +## 二十五、本课小结 + +- 字符串是有顺序的字符集合; +- 索引从 `0` 开始,`-1` 表示最后一个字符; +- 切片包含开始索引,不包含结束索引; +- `len()` 返回字符数量; +- 字符串可以使用 `for` 遍历; +- `strip()`、`lower()`、`replace()` 等方法返回新字符串; +- `in`、`find()`、`count()` 可以查找文本; +- `split()` 拆分字符串,`join()` 连接多个字符串; +- 字符串不可变,不能直接修改某个字符; +- f-string 可以控制小数和百分比格式。 + +## 二十六、验收标准 + +- [ ] 能使用正索引和负索引读取字符; +- [ ] 能使用切片取得字符串的一部分; +- [ ] 能使用 `len()` 和 `for` 分析文本; +- [ ] 能清理输入并统一英文大小写; +- [ ] 能查找和统计指定内容; +- [ ] 能使用 `split()` 和 `join()`; +- [ ] 能解释字符串不可变; +- [ ] 能完成并运行 `practice.py`; +- [ ] 能回答七道思考题。 diff --git a/01_python基础/1_7_字符串/practice.py b/01_python基础/1_7_字符串/practice.py new file mode 100644 index 0000000..60abb8a --- /dev/null +++ b/01_python基础/1_7_字符串/practice.py @@ -0,0 +1,101 @@ +# 第 1-7 课课堂练习:Agent 提示词文本分析器 +# +# 完成要求: +# 1. 根据注释使用字符串索引、切片和常用方法。 +# 2. 判断英文关键词时忽略大小写。 +# 3. 使用有意义的英文蛇形变量名。 +# 4. 不要删除题目注释。 +# 5. 完成后使用题目提供的文本测试结果。 + +# 练习一:使用 input() 接收一段 Agent 提示词。 +# 将原始输入保存到 raw_prompt。 + +# 练习二:使用 strip() 清理提示词两侧空白。 +# 将结果保存到 clean_prompt。 + +# 练习三:使用 len() 统计清理后的字符数量。 +# 将结果保存到 prompt_length。 + +# 练习四:创建用于忽略大小写判断的字符串。 +# 对 clean_prompt 调用 lower(),将结果保存到 lower_prompt。 + +# 练习五:使用 in 完成两个关键词判断: +# 1. lower_prompt 是否包含 "python",结果保存到 contains_python; +# 2. lower_prompt 是否包含 "agent",结果保存到 contains_agent。 + +# 练习六:使用 count() 统计 lower_prompt 中 "agent" 出现的次数。 +# 将结果保存到 agent_count。 + + +# 练习七:使用 split() 按照空白拆分 clean_prompt。 +# 不需要给 split() 传入参数。 +# 将结果保存到 word_list,再使用 len() 统计分割后的数量,保存到 word_count。 +# 提示:中文句子通常不会按每个汉字拆分;本练习统计的是空白分隔后的文本片段。 + +# 练习八:使用索引和切片取得摘要信息。 +# 先使用 if 判断 prompt_length 是否大于 0,避免空字符串索引越界: +# - 非空时:first_character 保存第一个字符,last_character 保存最后一个字符; +# - 空字符串时:两个变量都保存 "无"。 +# 再使用切片 clean_prompt[:10] 取得最多前 10 个字符,保存到 preview_text。 + +# 练习九:使用 replace() 将 clean_prompt 中的 "帮我" 替换为 "协助我"。 +# 将结果保存到 improved_prompt。 + +# 练习十:创建字符串 "Python,FastAPI,Django"。 +# 使用 split(",") 将它拆分并保存到 technology_list。 +# 再使用 " -> ".join(technology_list) 连接,保存到 technology_path。 + +# 练习十一:接收一个 Python 文件名并清理两侧空白。 +# 使用 endswith(".py") 判断是否为小写 .py 结尾,结果保存到 is_python_file。 + +# 练习十二:使用 30 个等号输出分隔线,再使用 f-string 输出分析报告: +# 1. 清理后的提示词; +# 2. 字符数量 prompt_length; +# 3. 文本片段数量 word_count; +# 4. 第一个字符和最后一个字符; +# 5. 前 10 个字符 preview_text; +# 6. 是否包含 Python; +# 7. 是否包含 Agent; +# 8. Agent 出现次数; +# 9. 替换后的提示词 improved_prompt; +# 10. 技术路线 technology_path; +# 11. 文件名是否以 .py 结尾。 + +# 练习十三:根据分析结果输出一条建议: +# - clean_prompt 为空:输出“提示词不能为空。” +# - 不包含 Agent:输出“建议明确说明 Agent 相关任务。” +# - 不包含 Python:输出“建议补充需要使用的编程语言。” +# - 同时包含 Agent 和 Python:输出“提示词包含核心技术信息。” +# 请使用 if...elif...else,并注意判断顺序。 + + +# 第一次测试建议输入: +# 提示词: 请使用 Python 帮我开发一个 Agent 应用 +# 文件名:agent_service.py +# +# 预期核心结果: +# contains_python = True +# contains_agent = True +# agent_count = 1 +# is_python_file = True +# 最终建议为“提示词包含核心技术信息。” + + +# 第二次测试建议输入: +# 提示词:请帮我整理学习计划 +# 文件名:notes.txt +# +# 预期核心结果: +# contains_python = False +# contains_agent = False +# is_python_file = False +# 最终建议优先提示缺少 Agent 相关任务。 + + +# 完成后进行自查: +# 1. 是否先 strip() 再进行长度和关键词分析; +# 2. 是否使用 lower_prompt 进行英文关键词判断; +# 3. 空字符串是否避免了索引越界; +# 4. 切片是否最多取得前 10 个字符; +# 5. split() 与 join() 的方向是否正确; +# 6. 最终建议的判断顺序是否正确。 diff --git a/01_python基础/1_7_字符串/strings.py b/01_python基础/1_7_字符串/strings.py new file mode 100644 index 0000000..d5d9d5a --- /dev/null +++ b/01_python基础/1_7_字符串/strings.py @@ -0,0 +1,105 @@ +# 第 1-7 课示例:字符串 +# +# 本文件集中演示字符串索引、切片、遍历和常见方法。 +# 建议运行后对照每段注释观察结果,不需要用户输入。 + + +# 一、索引 +# 正索引从 0 开始,负索引从 -1 开始倒数。 +technology = "Python" +print(f"第一个字符:{technology[0]}") +print(f"最后一个字符:{technology[-1]}") + + +# 二、长度 +# 空格和标点同样会计入字符串长度。 +prompt = "Python Agent" +print(f"提示词长度:{len(prompt)}") + + +# 三、切片 +# 切片包含开始索引,不包含结束索引。 +print(f"前三个字符:{technology[0:3]}") +print(f"从索引 3 到末尾:{technology[3:]}") +print(f"反转字符串:{technology[::-1]}") + + +# 四、遍历字符串 +# for 会依次取得字符串中的每一个字符。 +for character in "Agent": + print(f"当前字符:{character}") + + +# 五、清理两侧空白并转换大小写 +raw_text = " Python Agent " +clean_text = raw_text.strip() +lower_text = clean_text.lower() +upper_text = clean_text.upper() + +print(f"清理结果:{clean_text}") +print(f"小写结果:{lower_text}") +print(f"大写结果:{upper_text}") + + +# 六、替换文本 +# replace() 返回新字符串,不会直接修改原字符串。 +old_goal = "学习 Java 开发" +new_goal = old_goal.replace("Java", "Python") + +print(f"原目标:{old_goal}") +print(f"新目标:{new_goal}") + + +# 七、查找和统计 +analysis_text = "Python Agent Python FastAPI" +contains_agent = "Agent" in analysis_text +python_position = analysis_text.find("Python") +python_count = analysis_text.count("Python") + +print(f"是否包含 Agent:{contains_agent}") +print(f"Python 首次出现位置:{python_position}") +print(f"Python 出现次数:{python_count}") + + +# 八、判断开头与结尾 +file_name = "agent_service.py" +print(f"是否以 agent 开头:{file_name.startswith('agent')}") +print(f"是否为 Python 文件:{file_name.endswith('.py')}") + + +# 九、分割与连接 +# split() 得到列表;列表将在下一课系统学习。 +technology_text = "Python,FastAPI,Django" +technology_list = technology_text.split(",") +technology_path = " -> ".join(technology_list) + +print(f"分割结果:{technology_list}") +print(f"连接结果:{technology_path}") + + +# 十、字符串判断方法 +age_text = "18" +code_text = "Agent2026" + +print(f"年龄是否全部为数字:{age_text.isdigit()}") +print(f"代码是否只包含字母和数字:{code_text.isalnum()}") + + +# 十一、方法链 +# 先清理两侧空白,再统一转为小写。 +raw_answer = " YES " +clean_answer = raw_answer.strip().lower() +print(f"标准化回答:{clean_answer}") + + +# 十二、转义字符和原始字符串 +print("第一行\n第二行") +project_path = r"D:\Code\Python" +print(f"项目路径:{project_path}") + + +# 十三、f-string 数字格式 +total_hours = 6.5 +progress = 0.756 +print(f"总时长:{total_hours:.2f} 小时") +print(f"完成率:{progress:.1%}") diff --git a/README.md b/README.md index 5637861..335094d 100644 --- a/README.md +++ b/README.md @@ -189,11 +189,11 @@ Python/ ## 当前学习进度 - 当前阶段:第一阶段——Python 基础语法。 -- 当前课程:`1_5_条件判断`。 -- 当前状态:第五课学习中。 -- 已完成课程:`1_1_hello_world`、`1_2_变量与数据类型`、`1_3_输入与输出`、`1_4_运算符`。 -- 已创建课程目录:`01_python基础/1_1_hello_world/`、`01_python基础/1_2_变量与数据类型/`、`01_python基础/1_3_输入与输出/`、`01_python基础/1_4_运算符/`、`01_python基础/1_5_条件判断/`。 -- 下一步:阅读第五课讲义、运行分支示例并完成课堂练习。 +- 当前课程:`1_7_字符串`。 +- 当前状态:第七课学习中。 +- 已完成课程:`1_1_hello_world` 至 `1_6_循环`。 +- 已创建课程目录:`01_python基础/1_1_hello_world/` 至 `01_python基础/1_7_字符串/`。 +- 下一步:阅读第七课讲义、运行字符串示例并完成课堂练习。 ## 建议环境