文本是程序的日常。切片、方法、f-string 这三件套练熟,处理字符串就和呼吸一样自然。
字符串可能是你打交道最多的类型。它看起来简单,但细节不少:切片边界、不可变性、格式化对齐……这一篇把它们一次讲清。
你将学到
- 字符串的创建方式,索引与切片(含负索引、步长)
- 不可变性到底意味着什么
- 常用方法:
upper/lower/strip/split/join/replace/find/startswith - 转义字符与原始字符串
r"..." - f-string 详解:格式化数字、对齐、精度
str.format与%的老写法(看懂旧代码用)- 多行字符串、遍历与反转
前置知识
先读 上一篇:函数基础。
创建字符串
s1 = '单引号'
s2 = "双引号"
s3 = """三引号
可以换行"""
print(s3)
# 输出: 三引号 / 可以换行
print("他说:'你好'") # 输出: 他说:'你好'
print('他说:"你好"') # 输出: 他说:"你好"
单双引号功能一样,遇到引号冲突时换一种即可。
索引与切片
字符串是字符的序列,下标从 0 开始。
s = "Python"
print(s[0]) # 输出: P
print(s[-1]) # 输出: n 负索引从右往左,-1 是最后一个
print(s[-2]) # 输出: o
切片:s[起:止:步长],取头不取尾。
s = "Python"
print(s[0:3]) # 输出: Pyt (取 0、1、2,不含 3)
print(s[:3]) # 输出: Pyt (省略起点,从头开始)
print(s[3:]) # 输出: hon (省略终点,取到末尾)
print(s[::2]) # 输出: Pto (步长 2,隔一个取一个)
print(s[::-1]) # 输出: nohtyP (步长 -1,反转!)
print(s[1:6:2]) # 输出: bdf
不可变性
字符串是不可变的:不能原地修改某个字符。
s = "hello"
# ❌ TypeError: 'str' object does not support item assignment
# s[0] = "H"
# ✅ 用切片拼接出一个新字符串
s = "H" + s[1:]
print(s) # 输出: Hello
每次都重建新字符串,这是设计取舍:换来的是字符串可以作为字典键、可以安全共享。
常用方法速览
s = " Hello World "
print(s.upper()) # 输出: " HELLO WORLD "
print(s.lower()) # 输出: " hello world "
print(s.strip()) # 输出: "Hello World" 去掉两端空白
print(s.strip().split()) # 输出: ['Hello', 'World'] 按空白切分
name = "python"
print(name.upper(), name.capitalize()) # 输出: PYTHON Python
print("hello world".title()) # 输出: Hello World
raw = " data "
print(repr(raw.strip())) # 输出: 'data' 两端
print(repr(raw.lstrip()), repr(raw.rstrip())) # 只去左 / 只去右
print("xxhelloxx".strip("x")) # 输出: hello 去掉指定字符
csv = "苹果,香蕉,橘子"
fruits = csv.split(",")
print(fruits) # 输出: ['苹果', '香蕉', '橘子']
result = " / ".join(fruits) # join 是 split 的逆操作
print(result) # 输出: 苹果 / 香蕉 / 橘子
# ⚠️ join 只能拼字符串列表,数字要先 str() 转换
s = "I like apples, apples are tasty"
print(s.replace("apples", "oranges", 1)) # 只替换第一个
# 输出: I like oranges, apples are tasty
print(s.find("apples")) # 输出: 7 第一次出现的下标
print(s.find("zzz")) # 输出: -1 找不到返回 -1
print(s.count("apples")) # 输出: 2
print(s.index("apples")) # 输出: 7 找不到会抛异常
url = ""
print(url.startswith("https")) # 输出: True
print(url.endswith(".html")) # 输出: False
转义字符与原始字符串
反斜杠 \ 用来表示特殊字符:
print("第一行\n第二行") # \n 换行 → 第一行 / 第二行
print("列1\t列2") # \t 制表符 → 列1 列2
print("她说:\"你好\"") # \" 表示引号本身 → 她说:"你好"
print("反斜杠:\\") # \\ 表示一个反斜杠 → 反斜杠:\
不想让 \n 被解释成换行,用原始字符串(前缀 r):
print("C:\new\test") # \n 和 \t 被当成转义,结果乱了
print(r"C:\new\test") # ✅ 原样输出:C:\new\test
原始字符串在写正则、Windows 路径时非常有用。
f-string 详解
f-string(前缀 f,Python 3.6+)是目前最推荐的格式化方式。
name = "小明"
score = 95.5
print(f"{name} 的成绩是 {score}") # 输出: 小明 的成绩是 95.5
格式化数字:精度、千位、百分比
pi = 3.14159265
print(f"{pi:.2f}") # 输出: 3.14 保留 2 位小数
print(f"{1234567:,}") # 输出: 1,234,567 千位分隔
print(f"{0.256:.1%}") # 输出: 25.6% 百分比
print(f"{42:05d}") # 输出: 00042 补零到 5 位
print(f"{255:x}") # 输出: ff 十六进制
对齐与宽度
name = "小明"
print(f"[{name:>10}]") # 输出: [ 小明] 右对齐
print(f"[{name:<10}]") # 输出: [小明 ] 左对齐
print(f"[{name:^10}]") # 输出: [ 小明 ] 居中
print(f"[{name:*^10}]") # 输出: [****小明****] 用 * 填充
做表格对齐时非常好用:
rows = [("张三", 90), ("李四", 100), ("王五", 78)]
print(f"{'姓名':<6}{'分数':>6}")
for name, score in rows:
print(f"{name:<6}{score:>6}")
# 输出:
# 姓名 分数
# 张三 90
# 李四 100
# 王五 78
花括号内可以写表达式
a, b = 3, 5
print(f"{a} + {b} = {a + b}") # 输出: 3 + 5 = 8
print(f"名字长度:{len('小明')}") # 输出: 名字长度:2
print(f"{{这是花括号}}") # 输出: {这是花括号}
调试利器:= 说明符(Python 3.8+)
x, y = 42, 10
print(f"{x = }, {y = }") # 输出: x = 42, y = 10
print(f"{x + y = }") # 输出: x + y = 52
str.format 与 %(看懂旧代码用)
print("我叫{},今年{}岁".format("小明", 18)) # 输出: 我叫小明,今年18岁
print("我叫{name},今年{age}岁".format(name="小明", age=18))
print("{0}{1}{0}".format("A", "B")) # 输出: ABA
print("我叫%s,今年%d岁,身高%.1f米" % ("小明", 18, 1.75))
# 输出: 我叫小明,今年18岁,身高1.8米
%s 字符串、%d 整数、%f 浮点。这两种是历史写法,新代码请优先用 f-string。
多行字符串
poem = """床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。"""
# 三引号里的换行和缩进都会保留,所以内容最好顶格写
用括号隐式拼接长文本:
long_text = (
"这是第一段,"
"这是第二段,"
"它们会自动拼成一行。"
)
print(long_text) # 输出: 这是第一段,这是第二段,它们会自动拼成一行。
遍历与反转
s = "Python"
for ch in s:
print(ch, end=" ")
# 输出: P y t h o n
print(s[::-1]) # 输出: nohtyP 切片(最 Pythonic)
print("".join(reversed(s))) # 输出: nohtyP 用 reversed
回文判断
def is_palindrome(s):
"""判断忽略大小写后是否回文。"""
s = s.lower()
return s == s[::-1]
print(is_palindrome("Level")) # 输出: True
print(is_palindrome("Python")) # 输出: False
常见坑
坑一:切片边界不报错
s = "abc"
print(s[1:100]) # 输出: bc 切片越界不报错,能取多少取多少
# print(s[10]) # ❌ IndexError 但索引越界会报错
坑二:以为字符串能原地改
s = "hello"
# ❌ s[0] = "H" # 字符串不可变,不能这样改
# ✅ 重建新字符串
s = "H" + s[1:]
print(s) # 输出: Hello
坑三:join 拼了非字符串
nums = [1, 2, 3]
# ❌ TypeError: sequence item 0: expected str
# print(", ".join(nums))
# ✅ 先转成字符串
print(", ".join(str(n) for n in nums)) # 输出: 1, 2, 3
坑四:混淆 find 和 index
s = "hello"
print(s.find("z")) # 输出: -1 找不到返回 -1,不报错
# print(s.index("z")) # ❌ ValueError 找不到抛异常
需要"找不到也不崩"时用 find;需要"找不到就报错"时用 index。
小结
- 字符串用单/双/三引号创建;三引号可跨行。
- 索引从 0 起,负索引从右数;切片
[起:止:步长]取头不取尾,[::-1]反转。 - 字符串不可变,任何"修改"都是生成新字符串。
- 高频方法:
strip、split、join、replace、find、startswith。 - 原始字符串
r"..."让反斜杠不再转义,适合路径和正则。 - f-string 是格式化首选,支持精度
:.2f、千位:,、对齐:>10、调试{x = }。 - 多行字符串用三引号,或用括号隐式拼接。
- 遍历用
for ch in s,反转用s[::-1]。
延伸阅读
- 15-正则表达式:原始字符串的用武之地
- 27-列表元组字典集合:下一站,容器家族
上一篇:函数基础 · 下一篇:列表、元组、字典、集合
文章回复
0 条公开回复