第1章 1.3 字符串与 f-string 格式化
上回咱们聊了变量和基本数据类型,其中字符串(str)算是最常用的一个——毕竟程序嘛,就是处理文本的艺术。但上一章只提到了字符串"有这玩意儿",没来得及细说。
这一章咱们要把字符串彻底吃透,特别是 f-string 这个神器。学完之后,你处理文本就像用筷子夹菜一样熟练。
🎯 开场 3 分钟:为什么要学这个?
你有没有遇到过这些情况:
- 写了个程序,想把变量插进文字里,结果一堆
+号拼来拼去,自己都看晕了 - 字符串里有引号或者换行符,程序就报错了
- 从网上抓下来的数据,想按格式输出成报告,憋了半天写不出来
这些问题,学完这章全解决。
🧱 基础 25 分钟:核心概念
1.3.1 字符串的创建:引号是它的边界
字符串说白了就是用引号包起来的一串字符。
# 三种创建方式,效果一样
name = "小明" # 双引号
age = '18' # 单引号(注意!这是字符串不是数字)
intro = """我是小明,
今年18岁""" # 三引号,可以换行
说白了:引号就是字符串的"边界线",告诉 Python 从哪开始、到哪结束。
1.3.2 转义字符:字符串里的"特种兵"
有时候字符串里要放特殊字符,比如换行、Tab、引号本身。这时候就需要 转义字符 \,相当于给字符"化装"。
# \n 是换行,\t 是Tab,\' 是单引号本身
dialog = "他说:\"今天天气不错\"\n然后转身走了"
print(dialog)
输出:
他说:"今天天气不错"
然后转身走了
为什么要用:没有转义字符,你就没法在字符串里放引号——Python 会以为引号是字符串的边界。
小技巧:如果不想记转义字符,在字符串前面加 r,变成原始字符串(raw string):
path = r"C:\Users\小明\Desktop" # 不用写双反斜杠
print(path)
1.3.3 字符串切片:文本的"切肉刀"
字符串像一根绳子,可以切成若干段。语法是 字符串[起始:结束:步长]。
text = "Hello World"
print(text[0]) # H - 第1个字符
print(text[0:5]) # Hello - 第1到第5个字符
print(text[6:]) # World - 第7个到最后
print(text[-1]) # d - 倒数第1个
print(text[::-1]) # dlroW olleH - 倒序
生活类比:切片就像切面包,你告诉老板"我要从第几片到第几片",他就给你切好。

1.3.4 字符串常用方法:它的"内置技能"
字符串自带很多方法(函数),直接调用就行。记不住没关系,用到时查就行。
s = " Hello Python! "
print(s.strip()) # Hello Python! - 去掉首尾空格
print(s.lower()) # hello python! - 全部小写
print(s.upper()) # HELLO PYTHON! - 全部大写
print(s.replace("Python", "World")) # Hello World! - 替换
print(s.split(" ")) # ['', '', 'Hello', 'Python!', '', ''] - 分割成列表
print(len(s)) # 18 - 长度(这是函数不是方法)
为什么要用方法:不用自己写代码遍历字符,Python 已经帮你封装好了。
1.3.5 f-string:格式化界的"瑞士军刀"
终于到重头戏了!f-string 是 Python 3.6 引入的格式化神器,f 是 format(格式化)的意思。
核心思想:在字符串前面加个 f,里面用 {} 包住变量,Python 会自动把变量值"塞进去"。
name = "小明"
age = 18
height = 1.75
# 以前要这样写(麻烦)
intro_old = "我叫" + name + ",今年" + str(age) + "岁"
# 现在用 f-string(清爽)
intro = f"我叫{name},今年{age}岁,身高{height}米"
print(intro)
输出:
我叫小明,今年18岁,身高1.75米
生活类比:f-string 就像填空题的答题卡,你提前画好 {姓名} {年龄} 的空,考试时直接往里填。
1.3.6 f-string 表达式插值:{} 里能放算式
{} 里不只能放变量名,放表达式也行!
a = 10
b = 3
print(f"{a} + {b} = {a + b}") # 10 + 3 = 13
print(f"{a} * {b} = {a * b}") # 10 * 3 = 30
print(f"{a} / {b} = {a / b:.2f}") # 10 / 3 = 3.33(保留2位小数)
print(f"{a} 的平方是 {a**2}") # 10 的平方是 100
注意:{a / b:.2f} 这个 :2f 是格式化语法,意思是"保留2位小数"。

1.3.7 format() 方法:老派写法了解一下
在 f-string 出现之前,人们用 .format() 方法。虽然现在 f-string 更简洁,但看懂旧代码也很重要。
name = "小明"
score = 95
# format() 的三种姿势
print("我叫{},成绩是{}分".format(name, score))
print("我叫{0},成绩是{1}分,{0}加油!".format(name, score))
print("我叫{n},成绩是{s}分".format(n=name, s=score))
建议:新代码直接用 f-string,老代码认识就行。
🔥 实战 35 分钟:3 个递进的小项目
项目 1:个人信息卡(5 分钟)
需求:把用户的信息格式化成一张"名片"输出。
# 项目1:个人信息卡
name = "张小明"
age = 28
job = "软件工程师"
city = "北京"
salary = 25000
# 用 f-string 拼接
card = f"""
==============
姓名:{name}
年龄:{age}
职业:{job}
城市:{city}
月薪:{salary}元
==============
"""
print(card)
预期输出:
==============
姓名:张小明
年龄:28
职业:软件工程师
城市:北京
月薪:25000元
==============
一句话解释:f-string 让多行文本和变量混排变得超级简单。
项目 2:批量处理通讯录数据(15 分钟)
需求:从 CSV 格式的通讯录里读取数据,格式化输出每个人的信息。
# 项目2:批量处理通讯录
# 模拟 CSV 数据(实际可以用 open('file.csv') 读取)
contacts_csv = """姓名,电话,邮箱
张小明,13800138000,zhang@email.com
李华,13900139000,lihua@email.com
王芳,13700137000,wang@email.com"""
# 解析 CSV(简单版,不处理引号等复杂情况)
lines = contacts_csv.strip().split('\n')
headers = lines[0].split(',')
people = []
for line in lines[1:]:
values = line.split(',')
person = dict(zip(headers, values))
people.append(person)
# 格式化输出每个人信息
print("=== 通讯录(格式化后)===")
for p in people:
print(f"姓名:{p['姓名']}")
print(f"电话:{p['电话']}")
print(f"邮箱:{p['邮箱']}")
print("-" * 20)
预期输出:
=== 通讯录(格式化后)===
姓名:张小明
电话:13800138000
邮箱:zhang@email.com
--------------------
姓名:李华
电话:13900139000
邮箱:lihua@email.com
--------------------
姓名:王芳
电话:13700137000
邮箱:wang@email.com
--------------------
一句话解释:用 split() 把 CSV 拆成列表,再转成字典,用 f-string 格式化输出。
项目 3:待办清单小工具(15 分钟)
需求:做一个命令行待办清单,支持添加、查看、标记完成功能。
# 项目3:待办清单小工具
todos = []
def show_menu():
print(f"""
=== 待办清单 ===
当前有 {len(todos)} 项待办:
""")
if not todos:
print("(空)")
else:
for i, todo in enumerate(todos, 1):
status = "✓" if todo["done"] else "○"
priority = "🔥" if todo["priority"] == "高" else " "
print(f"{i}. [{status}] {priority}{todo['task']}")
print()
def add_task(task, priority="中"):
todos.append({"task": task, "priority": priority, "done": False})
print(f"✅ 已添加:{task}(优先级:{priority})")
def complete_task(index):
if 0 < index <= len(todos):
todos[index-1]["done"] = True
print(f"🎉 已完成:{todos[index-1]['task']}")
else:
print("❌ 无效序号")
# 演示用法
show_menu()
add_task("写周报", priority="高")
add_task("回复邮件", priority="中")
add_task("整理桌面", priority="低")
show_menu()
complete_task(1)
show_menu()
预期输出:
=== 待办清单 ===
当前有 0 项待办:
(空)
✅ 已添加:写周报(优先级:高)
✅ 已添加:回复邮件(优先级:中)
✅ 已添加:整理桌面(优先级:低)
=== 待办清单 ===
当前有 3 项待办:
1. [○] 🔥 写周报
2. [○] 回复邮件
3. [○] 整理桌面
🎉 已完成:写周报
=== 待办清单 ===
当前有 3 项待办:
1. [✓] 🔥 写周报
2. [○] 回复邮件
3. [○] 整理桌面
一句话解释:用字典存储每条待办的状态,f-string 把数据格式化成漂亮的输出。
💪 进阶 20 分钟:常见坑 + 性能小贴士
坑 1:引号嵌套搞混
❌ 错误写法:
# 这行不通!
s = "他说:"你好""
✅ 正确写法:
s = '他说:"你好"' # 外双内单
s = "他说:\"你好\"" # 转义
s = f'他说:"{"你好"}"' # f-string 混合
坑 2:f-string 里误用单引号包字符串
❌ 错误写法:
name = "小明"
s = f'你好,{name},'说'什么?' # 单引号嵌套会乱
✅ 正确写法:
s = f'你好,{name},{"说"}什么?' # 内部用双引号
s = f"你好,{name},'说'什么?" # 外部用双引号
坑 3:误把数字和字符串直接拼接
❌ 错误写法:
age = 18
s = "年龄:" + age # TypeError!
✅ 正确写法:
s = f"年龄:{age}" # f-string 自动转
s = "年龄:" + str(age) # 手动转
坑 4:转义字符没生效
❌ 错误写法:
path = "C:\Users\王五\Desktop" # \U 会被识别成转义序列
✅ 正确写法:
path = r"C:\Users\王五\Desktop" # 加 r 保持原始
path = "C:\\Users\\王五\\Desktop" # 双重转义
坑 5:切片越界不报错但结果不对
❌ 错误写法:
s = "Hello"
print(s[0:10]) # 不报错,但新手容易困惑
✅ 正确写法:
s = "Hello"
print(s[0:5]) # 明确范围
print(s[6:10]) # 返回空字符串,不会报错
性能小贴士:频繁拼接用 join
# 不好:每次 + 都会创建新字符串
result = ""
for i in range(1000):
result += str(i)
# 好:一次性拼接
result = "".join(str(i) for i in range(1000))
调试技巧:善用 f-string 打印中间变量
# 快速查看变量值(调试专用)
x = 10
y = 3
print(f"DEBUG: x={x}, y={y}, x/y={x/y:.2f}")
✏️ 练习题
练习 1(2 分钟):基础变形
- 输入:给定变量
name = "小红"age = 16 - 预期输出:
小红今年16岁了 - 提示:用 f-string,把变量塞进
{}里
练习 2(2 分钟):加个判断
- 输入:沿用练习 1 的变量,外加
has_gift = True - 预期输出:如果
has_gift为 True,输出小红今年16岁了,收到礼物啦!,否则输出小红今年16岁了 - 提示:在 f-string 里用
{变量 if 条件 else 变量}三元表达式
练习 3(3 分钟):处理新数据
- 输入:
data = "苹果,5,3.5|香蕉,3,2.8|橙子,8,4.2"(格式:水果,数量,单价) - 预期输出:列出每种水果的"水果名: 数量×单价=小计",如
苹果: 5×3.5=17.5元 - 提示:先用
split("|")分割,再用split(",")分割每项
练习 4(5 分钟):串联项目
- 输入:把项目 2 的 CSV 数据改成 JSON 格式
{"name": "张三", "score": 88} - 预期输出:格式化输出
张三同学考了88分,评级为A - 90分以上是A,80-89是B,60-79是C,60以下D
- 提示:把项目 2 的解析逻辑和项目 3 的条件判断组合起来
练习 5(5 分钟):报错分析
- 输入:以下代码为什么会报错?
name = "小明"
print(f'你好,{name},老师说:"今天要写{f-string}')
- 预期输出:说明错误原因并给出修正后的代码
- 提示:检查引号嵌套
作业:做一个「文本数据清洗工具」
需求描述:写一个工具,读取一批原始文本数据,进行清洗和格式化,输出整齐的报告。
功能点:
1. 能读取多行文本(可以硬编码在代码里)
2. 去除空格、转换大小写、统计字符数
3. 按指定格式输出(如:编号 | 原文本 | 清洗后 | 字数)
加分项:
1. 支持从列表里处理多条数据
2. 把结果导出成带边框的表格形式
验收标准:
- 能跑起来(复制进 Python 文件直接运行)
- 输出符合预期格式
- 代码有注释(每段功能用 # 说明)
提交方式:评论区贴代码或 GitHub 链接
📚 总结 + 资源
这一章学了 3 个核心点:
- 字符串切片:用 [start:end] 切分文本
- 转义字符:用 \ 处理特殊字符
- f-string:用 f"你好,{名字}" 格式化输出
延伸资源:
- 官方文档:https://docs.python.org/3/library/string.html
- 书籍:《Python编程:从入门到实践》第 4 章
- 视频:B 站小甲鱼《零基础学 Python》第 15 讲
互动钩子:你在做数据分析或者爬虫的时候,字符串处理有没有遇到过什么奇葩问题?评论区聊聊,老粉优先回复!
下一章我们要学「输入输出与运算符」,到时候你就能做出真正的交互式程序了——不再是只能 print 固定内容,而是能读取用户输入然后做计算。期待一下吧!

评论(0)