Files
PythonLearn/01_python基础/1_7_字符串/README.md

638 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第 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`
- [ ] 能回答七道思考题。