CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Python 语言基础/课时/字符串处理
RawBlame
课时目录12 节

Python 语言基础

  1. 01Python 是什么
  2. 02语法与缩进
  3. 03类型与变量
  4. 04条件与循环
  5. 05函数
  6. 06列表字典与集合
  7. 07字符串处理
  8. 08文件读写
  9. 09模块与 pip
  10. 10类与对象入门
  11. 11异常处理
  12. 12综合练习与下一步

字符串处理

切片、f-string、split/join。

30 分钟

字符串处理

这一课你将能做到

  1. 熟练使用切片、f-string 完成字符串的截取与格式化,写出对齐、保留小数等常见输出
  2. 熟练使用 split / join / strip / replace 完成文本的拆分、拼接、清洗
  3. 说出字符串「不可变」带来的行为规则,解释为什么所有「修改」方法都返回新字符串

为什么要学

脚本世界里 80% 的数据进门时是字符串:CSV 每行是字符串、命令行参数是字符串、网页抓下来的内容是字符串、大模型返回的也是字符串。处理文本的能力直接决定你写脚本的战斗力。而且字符串操作是面试笔试的常客——反转、回文、统计字符频次,全靠这一课的基本功。

人话:字符串像一串穿好的珠子,每颗珠子是一个字符,编号从 0 开始。你不能换掉某颗珠子(不可变),但可以随时「重新穿一串」——所有修改方法其实是给你一串新的。

先建立图像

 s = "Python"
 下标:  0 1 2 3 4 5
 字符:  P y t h o n
 负下标:-6-5-4-3-2-1

 s[0]  → 'P'      第一个
 s[-1] → 'n'      最后一个
 s[0:3] → 'Pyt'   含头不含尾
 s[::-1] → 'nohtyP'  反转

f-string 格式化速查:

f"{value:格式}"  →  冒号后面是格式说明
   :.2f   保留 2 位小数
   :>10   右对齐占 10 格      :<10 左对齐    :^10 居中
   :,     千分位逗号
   :%     百分比

跟着做

步骤 1:切片六连

新建 string_demo.py:

s = "Python"

print(s[0])        # P
print(s[-1])       # n
print(s[1:4])      # yth   含头不含尾
print(s[:2])       # Py    前 2 个
print(s[-2:])      # on    后 2 个
print(s[::-1])     # nohtyP  步长 -1 即反转

# 切片越界不报错(对比下标越界会报 IndexError)
print(s[2:100])    # thon

输出:

P
n
yth
Py
on
nohtyP
thon

切片是字符串最重要的操作,语法 [start:stop:step] 与列表完全一致——学一次两处用。

步骤 2:f-string 格式化全场景

name, price, qty = "机械键盘", 299.5, 3

# 基本插值:变量直接塞进大括号
print(f"{name} 单价 {price} 元")

# 表达式也能放进去
print(f"总价:{price * qty} 元")

# 保留 2 位小数
print(f"总价:{price * qty:.2f} 元")

# 千分位
big = 1234567.891
print(f"{big:,.2f}")             # 1,234,567.89

# 对齐:宽度 10
print(f"|{'id':<10}|{'name':^10}|{'price':>10}|")
print(f"|{1:<10}|{name:^10}|{price:>10.1f}|")

# 百分比
ratio = 0.875
print(f"完成度 {ratio:.1%}")      # 完成度 87.5%

# 调试神器:= 号同时打印变量名和值
x = 42
print(f"{x=}")                   # x=42

输出:

机械键盘 单价 299.5 元
总价:898.5 元
总价:898.50 元
1,234,567.89
|id        |   name   |     price|
|1         | 机械键盘  |     299.5|
完成度 87.5%
x=42

f-string 是 3.6+ 的标准做法,% 格式化和 .format() 只在维护老代码时认识即可。

步骤 3:不可变——所有方法都返回新串

s = "  Hello World  "

# strip 去两端空白(含换行、制表符)
print(repr(s.strip()))           # 'Hello World'

# lower / upper / replace 全都返回新串
print(s.strip().lower())         # hello world
print(s.replace("World", "Python"))  # '  Hello Python  '

# 原字符串纹丝不动
print(repr(s))                   # '  Hello World  '

# 所以必须接住返回值!
s = s.strip()                    # 重新绑定才生效
print(repr(s))                   # 'Hello World'

输出:

'Hello World'
hello world
  Hello Python
'  Hello World  '
'Hello World'

这是字符串第一坑:s.strip() 单独写一行,等于什么都没干。字符串方法和列表的 .sort()(原地改)行为模式不同——字符串一律「返回新的」。

步骤 4:split 与 join——文本处理的左手右手

line = "小明,88,92,79"

# split:字符串 → 列表
parts = line.split(",")
print(parts)                     # ['小明', '88', '92', '79']
name, *scores = parts            # 星号收走剩余部分
print(name, scores)              # 小明 ['88', '92', '79']

print("a b  c".split())          # 不传参:按任意空白切,自动去空串
# ['a', 'b', 'c']

# join:列表 → 字符串(注意是字符串调用它)
print("-".join(["2026", "10", "06"]))   # 2026-10-06
print(", ".join(["Python", "Java", "Go"]))  # Python, Java, Go

# 拼接大量字符串的正确姿势:join,而不是 += 循环累加
lines = ["第一行", "第二行", "第三行"]
print("\n".join(lines))

输出:

['小明', '88', '92', '79']
小明 ['88', '92', '79']
['a', 'b', 'c']
2026-10-06
Python, Java, Go
第一行
第二行
第三行

split 和 join 是一对镜像操作,CSV 行、路径、日志解析全靠它们来回转换。

步骤 5:查找判断一族

filename = "report_2026.pdf"

# startswith / endswith:判断前缀后缀(过滤文件常用)
print(filename.endswith(".pdf"))         # True
print(filename.startswith("report"))     # True

# find:找到返回下标,找不到返回 -1(index 找不到会抛异常)
print(filename.find("_"))                # 6
print(filename.find("xyz"))              # -1

# count:统计子串出现次数
print("banana".count("an"))              # 2

# isdigit / isalpha:类型校验(转换 int 前先检查)
print("123".isdigit())                   # True
print("12a".isdigit())                   # False

输出:

True
True
6
-1
2
True
False

步骤 6:转义字符与原始字符串

# 常见转义
print("第一行\n第二行")       # \n 换行
print("姓名:\"小明\"")        # \" 输出双引号
print("C:\\Users\\test")      # \\ 输出一个反斜杠

# Windows 路径的正确姿势:原始字符串 r""
path = r"C:\Users\test\file"   # r 前缀:反斜杠不当转义符
print(path)

# 三引号:跨行字符串
html = """
<html>
  <body>hello</body>
</html>
"""
print(html)

输出:

第一行
第二行
姓名:"小明"
C:\Users\test
C:\Users\test\file

<html>
  <body>hello</body>
</html>

讲清楚要点

  1. 字符串不可变:s[0] = "X" 直接 TypeError。所有「修改」类方法(strip/replace/upper…)都返回新字符串,必须重新绑定。字符串不可变换来的是可 hash(能当 dict 键)、多引用共享安全。
  2. f-string 是默认选择:大括号里可以放变量、表达式、函数调用;冒号后接格式说明(.2f、>10、,、%)。大括号本身要输出就写 {{ 和 }}。
  3. split/join 是文本转换的轴心:str → list 用 split,list → str 用 join。注意 join 是分隔符字符串的方法:",".join(lst)。
  4. 不传参的 split() 按任意空白切:多个空格、制表符、换行全算一个分隔符,还会丢弃首尾空白——清洗脏文本比 split(" ") 靠谱得多。
  5. find 返回 -1,index 抛异常:不在乎位置只判断「有没有」用 in;要下标用 find(温和)或 index(严格)。
  6. Windows 路径记得 r 前缀:r"C:\new\test" 里的 \n 不会被当成换行。写路径更推荐第 8 课的 pathlib,但它内部也依赖这个常识。
  7. 判断空字符串用 if not s::空串、None 都为假;if s == "" 漏掉 None 的情况。

你可能会懵的地方

  • strip() 能去掉字符串中间的空格吗? 不能,strip 只处理两端。去中间空格用 s.replace(" ", "") 或 "".join(s.split())。想只去左边/右边用 lstrip/rstrip。

  • 单引号、双引号、三引号怎么选? 功能几乎等价,惯例:普通字符串用单引号,字符串里含单引号时用双引号("it's"),跨行或含两种引号时用三引号。PEP 8 不强制,团队统一即可。

  • "3" + "5" 和 "3" * 3 是什么结果? "35" 和 "333"。+ 是拼接、* 是重复——对字符串做算术符号是这两层含义,和数字运算完全不同。"3" - "5" 则直接 TypeError。

  • 怎么遍历字符串? 和列表一样 for ch in s:,每个 ch 是单字符字符串。带下标用 for i, ch in enumerate(s):。字符串本质是字符序列,切片、in、len 全都通用。

  • 中文字符串的 len 是字符数还是字节数? Python 3 的 str 是 Unicode,len("你好") 是 2(字符数)。涉及文件大小、网络传输的「字节数」要把字符串编码后算:len("你好".encode("utf-8")) 是 6。

错法对照

错法问题正解
s.strip() 不接返回值原串不变,等于白做s = s.strip()
s[0] = "X"字符串不可变,TypeErrors = "X" + s[1:] 重建
循环里用 += 拼大字符串每次都新建串,O(n²)"".join(parts) 一次拼接
s.split(" ") 处理脏文本连续空格产生空串元素s.split() 不传参
写 Windows 路径 "C:\new\test"\n 被解释为换行r"C:\new\test" 原始字符串
用 == 判断字符串是否为空之外的逻辑混淆空串与 None判空 if not s:,判 None if s is None:
"age" + 18str + int 报 TypeErrorf"age{18}" 或 str(18)

卡点急救

  1. replace/strip 看似没生效:方法返回新串,原串不动。接住返回值:s = s.strip().lower()。
  2. TypeError: can only concatenate str:把数字直接和字符串相加。改 f-string 或 str() 转换。
  3. split 出来的数字不能运算:split 返回的都是字符串,逐个 int(x) 后再算;可用推导式 [int(x) for x in parts]。
  4. join 报 TypeError: sequence item 0: expected str instance:列表里混了非字符串(如数字)。先转换:",".join(str(x) for x in lst)。
  5. UnicodeDecodeError 读写文件时出现:编码不一致。文件读写显式传 encoding="utf-8"(第 8 课详述)。

面试常问

  • 字符串是不可变的,这样设计有什么好处? ①可 hash,能作为 dict 键和 set 元素;②多引用共享同一对象安全,无需防御性拷贝;③实现上可做驻留(interning)与缓冲优化。代价是每次「修改」都产生新对象,大量拼接需用 join 优化。

  • 为什么拼接大量字符串推荐 join 而不是 +=? += 每轮都可能创建新字符串并复制旧内容,整体 O(n²);join 先算总长一次性分配再填充,O(n)。数据量大时差距显著。

  • split() 和 split(" ") 的区别? 无参 split 按连续任意空白(空格/制表/换行)切分且忽略首尾空白,不产生空串;split(" ") 严格按单个空格切,连续空格会产生空字符串元素。清洗自然文本用无参版本。

  • Python 如何反转字符串?几种方法? 最惯用 s[::-1];也可 "".join(reversed(s))。顺带能答:字符串是序列,切片步长 -1 即逆序。

  • 字符串前缀 b、r、f、u 分别什么意思? b 字节串(bytes);r 原始字符串(反斜杠不转义,常用于正则与路径);f 格式化字符串(3.6+);u 在 Python 3 中无实际作用(3 的 str 本就是 Unicode,仅兼容 Python 2 写法)。

自测三问

  1. "Hello, World" 取出 World,写出切片;反转整个字符串写出切片。
  2. "{:>8.2f}".format(3.14159) 输出什么(或用 f-string 等价写法)?
  3. "a=1,b=2,c=3" 解析成 {"a": "1", "b": "2", "c": "3"},写出代码。

小结一句话

字符串是不可变的字符序列:切片截取、f-string 格式化、split/join 互相转换、方法一律返回新串要接住——这四条撑起脚本世界的文本处理。

延伸

  • 官方教程 — 字符串
  • str 方法完整列表
  • 下一课预告:文件读写——open、with 语句与 pathlib,让脚本能把结果真正存下来。
加载本节练习…
← 上一课列表字典与集合下一课 →文件读写