RSS
菜单
全部文章快讯开发科技深度热点

字符串与格式化(Python 从精通到入门 · 26)

内容摘要

文本是程序的日常。切片、方法、f-string 这三件套练熟,处理字符串就和呼吸一样自然。

文本是程序的日常。切片、方法、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-列表元组字典集合:下一站,容器家族

上一篇:函数基础 · 下一篇:列表、元组、字典、集合

— 全文完 —回到顶部 ↑
下载推广海报

文章推广海报

《字符串与格式化(Python 从精通到入门 · 26)》完整推广海报
DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。