本章摘要

  1. 核心目标:掌握字符串切片与常用方法,学会三种格式化输出,能独立生成格式化成绩单
  2. 核心知识点:字符串切片、upper/lower/strip/replace/split/join/find/count%格式化、format方法、f-string
  3. 实操产出:学生成绩存储与查询小工具(第二部分毕业综合案例)
  4. 前置基础:第7章字典、第5-6章循环与列表

一、写在前面

上一章我们学了字典,能以键值对的方式存储和查找数据。到这一章为止,你已经掌握了变量、条件判断、循环、列表和字典——Python 编程的核心地基已经打好了。

但你有没有注意到一个细节?从第1章的 print("Hello World") 开始,字符串就一直陪伴着我们。之前我们只是简单地用字符串存名字、存城市名,最多用 + 拼接一下。其实字符串远不止于此:

  • 从一段文字中截取中间几个字 → 切片
  • 把用户输入的多余空格去掉 → strip
  • 把一句话按空格拆成单词列表 → split
  • 把成绩、姓名整齐地填进一行报告里 → 格式化输出

这些操作在实际编程中天天用到。本章就来系统学习字符串的切片、常用方法和三种格式化输出方式,最后用一个"学生成绩存储与查询小工具"串联第二部分全部知识,完成循环与容器篇的毕业挑战。


二、字符串切片

2.1 字符串是不可变的序列

先记住一个结论:字符串就是一串字符按顺序排列组成的序列,每个字符都有自己的编号(索引)

name = "Python"
print(name[0])   # P,第1个字符,索引为0
print(name[1])   # y,第2个字符,索引为1
print(name[5])   # n,第6个字符,索引为5

Python 的索引从 0 开始,这和列表完全一样。除了正序索引,还支持负数索引——从末尾往前数,最后一个字符是 -1,倒数第二个是 -2,以此类推:

name = "Python"
print(name[-1])   # n,最后一个
print(name[-2])   # o,倒数第二个
print(name[-6])   # P,第一个(和 name[0] 等价)

在这里插入图片描述

2.2 切片语法:[起:止]

切片就是从字符串中"截取一段"。语法是 字符串[起始:结束]包含起始位置,不包含结束位置(左闭右开):

text = "HelloPython"
print(text[0:5])    # Hello,索引0~4
print(text[5:11])   # Python,索引5~10

几个常用简写:

text = "HelloPython"
print(text[:5])     # Hello,省略起始=从头开始
print(text[5:])     # Python,省略结束=到末尾
print(text[:])      # HelloPython,都省略=完整复制

2.3 带步长的切片:[起:止:步长]

切片还可以加第三个参数——步长,决定每隔几个字符取一次:

text = "HelloPython"
print(text[0:11:2])   # HloPto,每隔1个取1个(步长2)
print(text[::2])      # HloPto,从头到尾步长2
print(text[::-1])     # nohtyPolleH,步长-1=反转字符串

[::-1] 反转字符串是一个非常实用的技巧,记住它。

2.4 字符串不可变

字符串一旦创建,里面的字符不能通过索引修改:

name = "Python"
# name[0] = "J"  # 取消注释运行会触发 TypeError: 'str' object does not support item assignment

想修改怎么办?用后面要学的 replace 方法生成一个新字符串,或者用切片拼接:

name = "Python"
new_name = "J" + name[1:]   # Jython
print(new_name)

三、常用字符串方法

字符串自带了很多"方法"(可以理解为字符串专属的函数),用 字符串.方法名() 调用。下面学习最常用的 8 个。

在这里插入图片描述

3.1 upper()lower():大小写转换

upper() 把所有字母转大写,lower() 转小写:

text = "Hello World"
print(text.upper())    # HELLO WORLD
print(text.lower())    # hello world

方法不会改变原字符串,而是返回一个新字符串。原变量 text 的值不变。

3.2 strip():去除首尾空白

用户输入时经常多打空格,strip() 能去掉字符串首尾的空格、制表符和换行符:

raw_input = "   张三   "
clean = raw_input.strip()
print(f"[{clean}]")   # [张三]

还有 lstrip()(只去左边)和 rstrip()(只去右边),用法一样。

3.3 replace():替换

replace(旧, 新) 把字符串中的指定内容替换成新内容:

sentence = "我喜欢吃苹果,苹果很好吃"
new_sentence = sentence.replace("苹果", "香蕉")
print(new_sentence)   # 我喜欢吃香蕉,香蕉很好吃

第三个参数可以限制替换次数:

sentence = "苹果苹果苹果"
print(sentence.replace("苹果", "香蕉", 2))   # 香蕉香蕉苹果,只替换前2个

3.4 split():拆分

split() 把字符串按指定分隔符拆成列表,非常常用:

info = "张三,18,北京,编程"
parts = info.split(",")
print(parts)   # ['张三', '18', '北京', '编程']
print(parts[0])   # 张三

不传参数时默认按空白(空格、换行)拆分:

sentence = "Hello  Python  World"
words = sentence.split()
print(words)   # ['Hello', 'Python', 'World']

3.5 join():合并

join()split() 的逆操作,把列表里的字符串用指定分隔符拼成一个字符串:

words = ["Hello", "Python", "World"]
sentence = " ".join(words)
print(sentence)   # Hello Python World

# 用逗号拼接
csv_line = ",".join(words)
print(csv_line)   # Hello,Python,World

注意调用方式:是 分隔符.join(列表),不是 列表.join(分隔符)

3.6 find():查找

find(子串) 返回子串第一次出现的索引,找不到返回 -1

text = "Hello Python"
pos = text.find("Python")
print(pos)   # 6,从索引6开始

pos = text.find("Java")
print(pos)   # -1,没找到

3.7 count():计数

count(子串) 返回子串出现的次数:

text = "苹果香蕉苹果葡萄苹果"
print(text.count("苹果"))   # 3
print(text.count("香蕉"))   # 1
print(text.count("西瓜"))   # 0

3.8 方法速览表

方法 功能 示例 结果
upper() 全部转大写 "abc".upper() "ABC"
lower() 全部转小写 "ABC".lower() "abc"
strip() 去首尾空白 " hi ".strip() "hi"
replace(a, b) 把 a 替换成 b "a-b".replace("-", "+") "a+b"
split(sep) 按分隔符拆成列表 "a,b,c".split(",") ['a','b','c']
join(列表) 用分隔符拼接列表 "-".join(['a','b']) "a-b"
find(子串) 查找子串位置 "abc".find("b") 1
count(子串) 统计子串出现次数 "aba".count("a") 2

记住一个规律:字符串方法都不会修改原字符串,而是返回一个新字符串。如果想保存结果,记得用变量接收:text = text.strip()


四、格式化输出

格式化输出就是把变量值"填入"一段文字模板中。Python 有三种方式,从老到新依次是:% 格式化、format() 方法、f-string。

4.1 % 格式化(最古老)

%s(字符串)、%d(整数)、%f(浮点数)做占位符,类似 C 语言的 printf

name = "小明"
age = 18
score = 95.5

print("姓名:%s,年龄:%d,成绩:%.1f" % (name, age, score))
# 姓名:小明,年龄:18,成绩:95.5

%.1f 表示保留1位小数,%.2f 保留2位,以此类推。

这种方式现在不推荐日常使用,但你在看老代码时会经常遇到,需要能看懂。

4.2 format() 方法

{} 做占位符,调用 format() 方法填入值:

name = "小明"
age = 18
score = 95.5

print("姓名:{},年龄:{},成绩:{:.1f}".format(name, age, score))
# 姓名:小明,年龄:18,成绩:95.5

{} 里可以加序号来指定顺序:

print("{0}今年{1}岁,{0}在学Python".format("小明", 18))
# 小明今年18岁,小明在学Python

{:.1f} 的含义:冒号后是格式说明,.1f 表示保留1位小数。

4.3 f-string(推荐)

Python 3.6 引入,最简洁直观,日常首选

name = "小明"
age = 18
score = 95.5

print(f"姓名:{name},年龄:{age},成绩:{score:.1f}")
# 姓名:小明,年龄:18,成绩:95.5

在字符串前加 f,花括号 {} 里直接写变量名或表达式:

# 直接写表达式
a, b = 3, 4
print(f"{a} + {b} = {a + b}")   # 3 + 4 = 7

# 保留小数
price = 19.99
print(f"价格:{price:.2f} 元")   # 价格:19.99 元

# 对齐填充
name = "张三"
print(f"{'姓名':<6}|{'成绩':>6}")   # 左对齐6位 | 右对齐6位

4.4 三种方式对比

方式 写法 特点
% 格式化 "你好 %s" % name 最老,能看懂即可
format() "你好 {}".format(name) 较灵活,适合模板复用
f-string f"你好 {name}" 最简洁,日常首选

结论:自己写代码用 f-string,看老代码能读懂 %format 就行。前面章节其实已经在用 f-string 了,现在你正式学会它了。


五、Scratch 积木对照

Scratch Python 说明
「连接」积木(apple banana) 字符串 + 字符串f"{a}{b}" 把两段文字拼在一起

在这里插入图片描述

# Scratch「连接」积木 → Python 对照
first = "Hello"
second = "World"
# 方式1:用 + 拼接
print(first + " " + second)   # Hello World
# 方式2:用 f-string
print(f"{first} {second}")    # Hello World

Scratch 的「连接」积木把两块文字粘到一起,Python 里用 + 拼接或 f-string 直接嵌入,效果一样,但 f-string 更灵活——想插几个变量就写几个 {}


六、综合实战:学生成绩存储与查询小工具(第二部分毕业案例)

这是第二部分(循环与容器篇)的综合毕业案例,综合运用第4-8章全部知识:列表 + 字典 + for/while 循环 + 条件判断 + 字符串格式化。

功能设计:

  1. 录入学生姓名和成绩,存入字典
  2. 按条件查询(及格/不及格/全部)
  3. 统计平均分、最高分、最低分
  4. 格式化输出成绩单
# ========================================
# 学生成绩存储与查询小工具
# 综合运用:列表 + 字典 + for/while 循环 + 条件判断 + 字符串格式化
# ========================================

# 用列表存储所有学生,每个学生是一个字典
students = []

print("=" * 40)
print("    学生成绩存储与查询系统 v1.0")
print("=" * 40)

# 1. 录入学生信息
while True:
    print()
    name = input("请输入学生姓名(输入 q 结束录入):").strip()
    if name.lower() == "q":
        break

    score = float(input(f"请输入 {name} 的成绩(0-100):"))
    if score < 0 or score > 100:
        print("⚠️ 成绩无效,请重新录入该学生")
        continue

    # 每个学生存为一个字典,追加到列表
    student = {"姓名": name, "成绩": score}
    students.append(student)
    print(f"✅ 已录入:{name} - {score} 分")

# 2. 查询功能
print()
print("=" * 40)
print("  查询菜单")
print("  1. 查看全部成绩")
print("  2. 查看及格的学生(>=60)")
print("  3. 查看不及格的学生(<60)")
print("  4. 按姓名搜索")
print("=" * 40)

choice = input("请选择查询方式(1-4):")

# 3. 根据选择筛选数据
if choice == "1":
    result = students
    title = "全部学生成绩"
elif choice == "2":
    result = [s for s in students if s["成绩"] >= 60]
    title = "及格学生成绩"
elif choice == "3":
    result = [s for s in students if s["成绩"] < 60]
    title = "不及格学生成绩"
elif choice == "4":
    search_name = input("请输入要搜索的姓名:").strip()
    result = [s for s in students if search_name in s["姓名"]]
    title = f"搜索「{search_name}」的结果"
else:
    result = []
    title = "无效选择"

# 4. 格式化输出成绩单
print()
print("=" * 40)
print(f"  {title}")
print("=" * 40)
print(f"{'序号':<6}{'姓名':<10}{'成绩':<8}{'等级':<6}")
print("-" * 40)

if len(result) == 0:
    print("  暂无数据")
else:
    for i, s in enumerate(result, 1):
        # 根据成绩判定等级
        if s["成绩"] >= 90:
            grade = "优秀"
        elif s["成绩"] >= 80:
            grade = "良好"
        elif s["成绩"] >= 60:
            grade = "及格"
        else:
            grade = "不及格"

        # f-string 格式化输出,< 表示左对齐
        print(f"{i:<6}{s['姓名']:<10}{s['成绩']:<8.1f}{grade:<6}")

print("-" * 40)

# 5. 统计信息(基于全部学生)
if len(students) > 0:
    scores = [s["成绩"] for s in students]
    avg = sum(scores) / len(scores)
    max_score = max(scores)
    min_score = min(scores)
    pass_count = sum(1 for s in scores if s >= 60)

    print(f"  总人数:{len(students)} 人")
    print(f"  平均分:{avg:.1f}")
    print(f"  最高分:{max_score:.1f}")
    print(f"  最低分:{min_score:.1f}")
    print(f"  及格率:{pass_count}/{len(students)}{pass_count/len(students)*100:.0f}%)")
else:
    print("  未录入任何学生数据")

print("=" * 40)

运行效果:

========================================
    学生成绩存储与查询系统 v1.0
========================================

请输入学生姓名(输入 q 结束录入):张三
请输入 张三 的成绩(0-100):95
✅ 已录入:张三 - 95.0 分

请输入学生姓名(输入 q 结束录入):李四
请输入 李四 的成绩(0-100):58
✅ 已录入:李四 - 58.0 分

请输入学生姓名(输入 q 结束录入):王五
请输入 王五 的成绩(0-100):82
✅ 已录入:王五 - 82.0 分

请输入学生姓名(输入 q 结束录入):q

========================================
  查询菜单
  1. 查看全部成绩
  2. 查看及格的学生(>=60)
  3. 查看不及格的学生(<60)
  4. 按姓名搜索
========================================
请选择查询方式(1-4):1

========================================
  全部学生成绩
========================================
序号  姓名      成绩    等级  
----------------------------------------
1     张三      95.0    优秀  
2     李四      58.0    不及格
3     王五      82.0    良好  
----------------------------------------
  总人数:3 人
  平均分:78.3
  最高分:95.0
  最低分:58.0
  及格率:2/3(67%)
========================================

分步拆解:

  1. 数据结构设计:用列表 students 存所有学生,每个学生是一个字典 {"姓名": ..., "成绩": ...}。列表负责存"一堆",字典负责存"一个人的多个属性"——这是列表+字典组合的经典用法

  2. while 循环录入while True 无限循环,输入 qbreak 跳出。成绩不合法时 continue 跳过本次循环,重新录入——这是第5章学过的循环控制

  3. strip() 清理输入input(...).strip() 去掉用户输入首尾可能多打的空格,这是本章学的字符串方法

  4. 查询菜单:用 if-elif-else 处理4种查询方式。列表推导式 [s for s in students if ...] 是第6章列表知识的应用,按条件筛选数据

  5. f-string 格式化成绩单f"{i:<6}{s['姓名']:<10}..."< 左对齐、数字控制宽度,让输出像表格一样整齐——这正是格式化输出的实际应用

  6. 统计信息:用 sum()max()min() 配合列表推导式快速算出平均分、最高分、最低分。及格率用 sum(1 for s in scores if s >= 60) 统计及格人数,再算百分比

这个案例串联了第二部分全部知识:列表(存多人数据)、字典(存单人属性)、for 循环(遍历输出)、while 循环(循环录入)、break/continue(循环控制)、条件判断(等级判定、菜单选择)、字符串方法(strip)、f-string 格式化(成绩单对齐输出)。能独立写出来,说明第二部分已经完全掌握了。


七、常见报错速查表

报错信息 出现场景 原因 解决方法
TypeError: 'str' object does not support item assignment 试图通过索引修改字符串 字符串不可变 replace() 或切片拼接生成新字符串
IndexError: string index out of range 访问不存在的索引 索引超出字符串长度 检查索引范围,最大索引 = len(s) - 1
TypeError: can only concatenate str to str 字符串和数字用 + 拼接 类型不兼容 str() 转换数字,或改用 f-string
AttributeError: 'str' object has no attribute 'xxx' 调用不存在的字符串方法 方法名拼写错误 查阅方法速览表,确认方法名正确
ValueError (split 场景) split 结果按索引取值越界 分隔符不匹配导致结果数量少于预期 print 查看 split 结果再取值
KeyError (format 场景) format{} 数量与参数不匹配 占位符和参数个数对不上 检查 {} 个数与 format() 参数数量

九、本章小结

本章你掌握了字符串操作和格式化输出的完整体系:

  1. 字符串切片——[起:止:步长],左闭右开,[::-1] 反转字符串
  2. 8个常用方法——upper/lower 转大小写、strip 去空白、replace 替换、split 拆分、join 合并、find 查找、count 计数
  3. 三种格式化输出——% 格式化(能读懂)、format() 方法(灵活复用)、f-string(日常首选)
  4. 字符串不可变——所有方法都返回新字符串,不会修改原字符串

到本章为止,第二部分(循环与容器篇)全部学完。你已经能熟练使用列表、字典、for/while 循环、条件判断和字符串操作——这些是 Python 编程最常用的工具组合。

往期回顾:

《Python 零基础入门:从积木到代码》专栏序

零基础学 Python 第1章 | 全平台装环境 + VS Code 配置 + 第一个 Hello World

零基础学 Python 第2章 | print 输出 + 变量赋值 + input 交互输入

零基础学 Python 第3章 | 条件判断:if / elif / else

零基础学 Python 第 4 章 | for 循环与 range():让程序帮你重复干活

零基础学 Python 第 5 章 | while 循环与循环嵌套:让程序看着条件自己干活

零基础学 Python 第 6 章 | 元组与集合:不可变数据与自动去重

零基础学 Python 第7章 | 字典 dict:键值对存储

下一章预告:前面几章我们写了不少重复的代码,比如成绩判等级的逻辑在多个程序里都出现过。如果能把一段代码"打包"起来,起个名字,需要时直接调用,岂不是省事很多?下一章学习函数基础——def 定义函数、参数传递、返回值,让你的代码从"一整坨"变成"模块化积木"。


文末资源区

资源 说明
Python 官方文档 - 字符串方法 https://docs.python.org/3/library/stdtypes.html#string-methods
Python 官方文档 - 字符串格式化 https://docs.python.org/3/library/string.html#formatstrings
Python 官方文档 - f-string https://docs.python.org/3/reference/lexical_analysis.html#f-strings
Python 官方文档 - 切片 https://docs.python.org/3/library/functions.html#slice
本章完整源码 chapter8_all.py(关注梅雅达编程笔记,评论领资料)

每节课都配套课后练习题与完整源码。代码报错、看不懂知识点,可在评论区粘贴问题,逐一解答!
欢迎关注梅雅达编程笔记,持续分享Python零基础学习内容

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐