数据结构 · #5 / 11
字符串 + 文本处理
不可变性、切片、格式化与方法
为什么重要
大多数面试题都涉及文本。精通字符串能省下时间。
核心思想
字符串是不可变的序列。切片会产生新的字符串;你永远不会就地修改它。f"" 字符串是现代的格式化方式。
试一试
切片——s[start:stop:step]:
s = "abcdefghij"
print(s[2:5]) # 'cde'
print(s[:4]) # 'abcd'
print(s[-3:]) # 'hij'
print(s[::2]) # 'acegi'
print(s[::-1]) # 'jihgfedcba' (reverse)
常用方法——split、strip、join、replace、find:
raw = " Hello, World, Python "
parts = [p.strip() for p in raw.split(",")]
print(parts)
print(",".join(parts))
print("python" in raw.lower())
格式化——f-string 每一次都胜过 .format() 和 %:
name, score = "Ada", 0.875
print(f"{name:>10} | {score:6.1%}")
print(f"{name!r:<10} | binary: {42:08b}")
# Multi-line + expressions
print(f"""
sum: {2 + 3}
list: {[i*i for i in range(5)]}
""")
你必须掌握的字符串方法
| 类别 | 方法 | 作用 |
| --- | --- | --- |
| 清理 | strip、lstrip、rstrip | 去除空白字符 |
| 大小写 | lower、upper、title、capitalize | 改变大小写 |
| 查找 | find、index、count | 定位与计数 |
| 匹配 | startswith、endswith | 前缀/后缀检查 |
| 切分/拼接 | split、rsplit、splitlines、'sep'.join(...) | 分词与拼接 |
| 替换 | replace | 替换 |
| 检查 | isalnum、isalpha、isdigit、isnumeric、isspace | 校验 |
name = " Ada Lovelace "
print(name.strip().lower())
"data-science".split("-")
"-".join(["a", "b"])
回文归一化模式
一个可复用的套路:只保留字母和数字字符并把它们转为小写,然后与反转后的字符串比较。
def normalize(s: str) -> str:
return "".join(ch.lower() for ch in s if ch.isalnum())
快速检查
- 问: 字符串可变吗? 答: 不可变。
小练习
- 用两种方法反转一个字符串。
- 数一数一个句子里的元音字母。
- 去除标点并转为小写。
该做与不该做
- 该做:比较之前先用
s.strip()。 - 不该做:在循环里用
+来拼接字符串。
深入一点——bytes 与 str
在 Python 3 中,文本和二进制是不同的类型:
str= 文本(Unicode)bytes= 原始二进制
编码(encode)把文本转成字节,解码(decode)再转回来:
b = "hello".encode("utf-8")
text = b.decode("utf-8")常见错误
- 错误: 试图修改
s[0]。 修正: 构建一个新字符串。 - 错误: 在循环里使用
+。 修正: 使用"".join(...)。 - 错误: 用了
find却不检查-1。 修正: 验证返回结果。
关键要点
- 字符串是不可变的——
s.upper()返回一个新字符串,不会修改s。 - 切片创建一个新字符串;
[::-1]反转,[::2]隔一个取一个。 - f-string 可以嵌入表达式和格式说明(
{x:>10.2f}、{x!r}、{x:08b})。 str.split()/"sep".join(iterable)是拼接/切分的惯用法。- 用
.join提升性能;比较之前先归一化文本。