考点 5. Python 的字符串类型
掌握字符串的输入输出和相关处理方法,能够在编程中使用字符串方法处理问题。
字符串是 Python 中用来表示文本数据的一种数据类型,本质是字符的有序序列(可以是字母、数字、符号、中文等任意字符)。简单来说,Python 中用引号包裹的文本都是字符串。
字符串有有序性和不可变性两个关键特性。
- (1)有序:字符有固定的顺序,如“abc”和“cba”是不同的字符串。
- (2)不可变:字符串创建后,内部的字符不能被修改,例如,不能直接把“abc”的第一个字符改成“x”。
一、字符串的表示
Python 中创建字符串有 3 种常用方式,核心是用引号包裹,单引号、双引号、三引号均可。
1. 单引号/双引号(最常用)
单引号和双引号的功能完全一致,选一种即可。如果字符串内部包含引号,那么可交叉使用,避免报错。
# 单引号创建
str1 = 'Hello Python'
print(str1) # 输出:Hello Python
# 双引号创建
str2 = "你好,Python"
print(str2) # 输出:你好,Python
# 交叉使用引号(避免内部引号冲突)
str3 = 'He said: "Python is easy!"' # 内部双引号,外部单引号
str4 = "It's a cat" # 内部单引号,外部双引号
print(str3) # 输出:He said: "Python is easy!"
print(str4) # 输出:It's a cat
2. 三引号(支持多行字符串)
用“""”或“'''”包裹,可直接创建换行的多行字符串,常用于注释、文档字符串。
# 多行字符串
str5 = """这是第一行
这是第二行
这是第三行"""
print(str5)
# 输出:
# 这是第一行
# 这是第二行
# 这是第三行
3. 空字符串
不含任何字符的字符串用不包裹任何内容的引号表示,常用于初始化变量。
str6 = "" # 空字符串
print(len(str6)) # 输出:0(长度为 0)
二、字符串的特点及基本操作
1. 不可变
字符串创建后,无法修改其中的单个字符,强行修改会报错。若需修改,则只能创建新字符串。
s = "abc"
# s[0] = "x" # 报错:TypeError(字符串不可变)
# 正确修改方式:拼接新字符串
new_s = "x" + s[1:]
print(new_s) # 输出:xbc
2. 有序性(可索引、切片)
因为字符串是“字符的有序序列”,所以可以通过索引(取单个字符)、切片(取子字符串)访问。
- (1)索引:从 0 开始(正向),或从 -1 开始(反向,-1 表示最后一个字符)。
- (2)切片:语法为 s[起始索引:结束索引:步长],左闭右开(包含起始,不包含结束)。
s = "Python" # 索引访问
print(s[0]) # 输出:P(第一个字符)
print(s[-1]) # 输出:n(最后一个字符)
# 切片访问
print(s[1:4]) # 输出:yth(取索引 1-3 的字符)
print(s[::2]) # 输出:Pto(步长 2,隔一个取一个)
print(s[::-1]) # 输出:nohtyP(步长 -1,反转字符串)
3. 可拼接、重复
用“+”拼接多个字符串,用“*”表示重复字符串。
# 拼接
s1 = "Hello"
s2 = "World"
print(s1 + " " + s2) # 输出:Hello World
# 重复
print("-" * 10) # 输出:----------(重复 10 次)
print(s1 * 3) # 输出:HelloHelloHello
三、字符串的输入/输出
1. 输入
字符串的输入是获取用户从控制台输入的文本。Python 中唯一的基础输入函数是 input(),无论输入什么内容,返回值都是字符串。
- (1)基础输入:获取用户输入。
# 1. 基础用法:提示文字 + 获取输入
name = input("请输入你的姓名:")
print(f"你输入的姓名是:{name}")
# 示例执行过程:
# 控制台显示:请输入你的姓名:
# 用户输入:小明 → 按回车
# 输出:你输入的姓名是:小明
# 2. 无提示文字的输入
content = input()
print(f"你输入的内容是:{content}")
- (2)关键注意点:input() 的返回值永远是字符串。
如果需要获取数字(整数/浮点数),那么必须手动转换类型,否则会报错。
# 错误示例:直接用输入的字符串做算术运算
age = input("请输入你的年龄:")
# print(age + 1) # 报错:TypeError(字符串和整数不能相加)
# 正确做法:转换类型
age = int(input("请输入你的年龄:")) # 转整数
print(f"明年你的年龄是:{age + 1}")
# 转浮点数(如输入身高、成绩)
height = float(input("请输入你的身高(米):"))
print(f"身高保留 2 位小数:{height:.2f}")
2. 输出
字符串的输出是将文本、变量等内容展示在控制台上,或写入文件,最基础、最常用的是 print() 函数。
# 1. 打印字符串字面量(单/双引号均可)
print("Hello Python") # 输出:Hello Python
print('你好,世界') # 输出:你好,世界
# 2. 打印字符串变量
msg = "今天学习字符串输入输出"
print(msg) # 输出:今天学习字符串输入输出
# 3. 打印多个内容
name = "小明"
age = 18
print("姓名:",name,"年龄:",age) # 输出:姓名: 小明 年龄: 18
四、格式化字符串
格式化字符串(String Formatting)是 Python 中一种将“固定文本”和“动态变量/表达式”结合成一个完整字符串的技术。在输出字符串内容时,格式化字符串能够统一文本格式,简化动态文本拼接,提升代码可读性。
Python 有 3 种主流的格式化方式,核心逻辑都是“模板+占位符+填充值”,只是语法有所不同,见表 8-15 所列。
表 8-15 格式化字符串
| 方 式 | 核心语法 | 通俗理解 | 适用场景 |
|---|---|---|---|
| f-string(推荐) | f"模板{变量/表达式}" | 直接在模板里写变量,最直观 | Python3.6+,日常开发学习的首选 |
| format()方法 | "模板{}".format(变量) | 把变量“传给”模板的占位符 | 兼容低版本 Python(3.5-) |
| % 格式化(旧式) | "模板%s"%变量 | 用%把变量“贴”到模板上 | 仅维护旧代码时使用 |
1. f-string
f-string(Formatted String Literals)是 Python 3.6 及以上版本引入的字符串格式化方式,在字符串前加 f 或 F,通过{}包裹变量/表达式,直接将动态内容嵌入字符串中。
(1)基本语法
# 基本格式:f/F + 字符串,{}内是要嵌入的内容
f"固定文本{变量/表达式}固定文本"
F"固定文本{变量/表达式}固定文本" # F 和 f 的效果完全一致
(2)基础用法
# 字符串变量
name = "小明"
print(f"你好,{name}!") # 输出:你好,小明!
# 数字变量(整数/浮点数)
age = 18
score = 95.5
print(f"年龄:{age},成绩:{score}") # 输出:年龄:18,成绩:95.5
# 算术表达式
a = 10
b = 20
print(f"10 + 20 = {a + b}") # 输出:10 + 20 = 30
print(f"10 × 20 = {a * b}") # 输出:10 × 20 = 200
print(f"10² = {a ** 2}") # 输出:10² = 100
# 字符串表达式
s = "python"
print(f"大写:{s.upper()},长度:{len(s)}") # 输出:大写:PYTHON,长度:6
(3)格式控制
- ①数字相关格式符:针对整数、浮点数的格式控制,是最需要掌握的参数,具体见表 8-16 所列。
表 8-16 f-string 数字格式控制
| 参数语法 | 作 用 | 示 例 | 输出结果 |
|---|---|---|---|
| :.nf | 浮点数保留 n 位小数(四舍五入) | f"{3.1415:.2f}" | 3.14 |
| :0nd | 整数补零到 n 位(不足补 0) | f"{123:06d}" | 000123 |
| :.n% | 转百分比(×100+保留 n 位小数) | f"{0.85:.1%}" | 85.0% |
| :, | 数字加千分位分隔符 | f"{1234567:,}" | 1,234,567 |
| :n | 指定数字的显示宽度(默认右对齐) | f"{88:5d}" | 88(3 个空格) |
| :.ne | 科学计数法(保留 n 位小数) | f"{1234.56:.2e}" | 1.23e+03 |
import math
# 保留小数
pi = math.pi
print(f"π 保留 3 位小数:{pi:.3f}") # 输出:3.142
# 整数补零
student_id = 45
print(f"学号补零到 5 位:{student_id:05d}") # 输出:00045
# 百分比格式
pass_rate = 0.928
print(f"通过率:{pass_rate:.2%}") # 输出:92.80%
# 千位分隔符
salary = 9876543
print(f"年薪:{salary:,}元") # 输出:9,876,543 元
# 科学计数法
num = 12345.6789
print(f"科学计数法:{num:.2e}") # 输出:1.23e+04
- ②字符串的相关格式符:控制字符串的对齐、宽度、截断,常用于文本排版,具体见表 8-17 所列。
表 8-17 f-string 字符串串格式控制
| 参数语法 | 作用 | 示例 | 输出结果 |
|---|---|---|---|
| :<n | 字符串左对齐,总宽度 n(不足补空格) | f'{"小明":<8}' | 小明______(6 个空格) |
| :>n | 字符串右对齐,总宽度 n | f'{"小明":>8}' | ______小明 |
| :^n | 字符串居中对齐,总宽度 n | f'{"小明":^8}' | ___小明___ |
| :.n | 截断字符串,仅保留前 n 个字符 | f'{"Python 教程":.4}' | Python |
| :填充符^n | 居中对齐+自定义填充符(如一、*等) | f'{"标题":^-10}' | -----标题----- |
# 对齐与宽度
name = "小红"
print(f"左对齐:{name:<8}年龄:18") # 输出:左对齐:小红 年龄:18
print(f"右对齐:{name:>8}年龄:18") # 输出:右对齐: 小红年龄:18
print(f"居中:{name:^8}年龄:18") # 输出:居中: 小红 年龄:18
# 自定义填充符
print(f"【{name:*^8}】") # 输出:【*****小红****】
# 截断字符串
long_text = "Python 是最好的编程语言"
print(f"截断后:{long_text:.6}") # 输出:截断后:Python
2. format()方法
str.format() 是 Python 字符串的内置方法,通过占位符{} 标记字符串中的动态位置,再将 format()的参数填充到占位符中,实现字符串格式化。
(1)基本语法
# 基本结构:模板字符串.format(参数1,参数2,…)
"固定文本{占位符}固定文本".format(值1,值2,…)
模板字符串:包含占位符{}的字符串,定义输出的固定格式。
format()参数:要填充到占位符中的动态值(变量、表达式、函数返回值等)。
占位符{}:标记动态内容的位置,可通过语法控制匹配规则和显示格式。
(2)format()的核心用法
format()的灵活性体现在"参数如何匹配占位符"上,有 3 种常用匹配方式,覆盖所有基础场景。
- ①位置参数
按参数的位置顺序填充到占位符中,无须指定名称,简单直观。
a. 无编号占位符(按顺序匹配)
# 模板中占位符无编号,按format()参数顺序填充
template = "姓名:{},年龄:{},成绩:{}"
# 按顺序:"小明"→第一个{},18→第二个{},95.5→第三个{}
print(template.format("小明",18,95.5))
# 输出:姓名:小明,年龄:18,成绩:95.5
# 支持表达式作为参数
print("10 + 20 = {}".format(10 + 20)) # 输出:10 + 20 = 30
b. 有编号占位符(指定位置匹配)
在占位符中写数字(从 0 开始),从而指定使用 format()中的某个参数填充,可重复使用参数。
template = "第{0}名:{1},总分{2}:{1} 的年龄是{0}岁"
# {0}→第一个参数 18,{1}→第二个参数"小红",{2}→第三个参数 98
print(template.format(18,"小红",98))
# 输出:第 18 名:小红,总分 98:小红的年龄是 18 岁
- ②关键字参数
在占位符中写自定义关键字,在 format()中用"关键字=值"的方式传参,与参数顺序无关,可读性极强。
# 模板中占位符是关键字:name/age/score
template = "姓名:{name},年龄:{age},成绩:{score}"
# 按关键字匹配,顺序可任意
print(template.format(age=19,score=88.5,name="小李"))
# 输出:姓名:小李,年龄:19,成绩:88.5
# 结合变量使用(实战常用)
name = "小张"
age = 20
print(template.format(name=name,age=age,score=90))
# 输出:姓名:小张,年龄:20,成绩:90
- ③索引/属性匹配(处理容器/对象)
直接在占位符中访问列表、字典的索引/键,或对象的属性,无须提前取值。
a. 列表/元组的索引匹配
# 列表作为参数,占位符中用[索引]访问元素
student = ["小王",21,85.0]
template = "姓名:{0[0]},年龄:{0[1]},成绩:{0[2]}"
print(template.format(student))
# 输出:姓名:小王,年龄:21,成绩:85.0
# 多个列表参数
s1 = ["小红",18]
s2 = ["小明",19]
template = "S1:{0[0]}({0[1]}岁),S2:{1[0]}({1[1]}岁)"
print(template.format(s1,s2))
# 输出:S1:小红(18 岁),S2:小明(19 岁)
b. 字典的键匹配
# 字典作为参数,占位符中用[键名]访问值(注意字典前加 ** 解包更简洁)
student = {"name":"小李","age":22,"score":92}
# 方式1:用[键名]
template = "姓名:{0[name]},年龄:{0[age]}"
print(template.format(student))
# 输出:姓名:小李,年龄:22
# 方式2:解包字典(推荐,更简洁)
template = "姓名:{name},成绩:{score}"
print(template.format(**student))
# 输出:姓名:小李,成绩:92
【注】f-string 和 format()方法的格式说明符几乎完全一致,仅在语法书写形式上有很小差异,核心规则和效果完全通用。
3. % 占位符
% 占位符是 Python 最早的字符串格式化方式,模仿 C 语言的 printf()函数。通过字符串中的 % 开头的占位符标记动态位置,再用 % 运算符将右侧的值填充到占位符中。基本语法结构如下。
# 基本结构:模板字符串 % 待填充的值(单个值/元组/字典),
"固定文本 % 占位符固定文本" % 填充值。
模板字符串:包含 % 开头占位符的字符串(如 %s、%d)。
% 运算符:连接模板字符串和填充值。
# 1. 单个占位符(字符串)
print("你好,%s!" % "小红") # 输出:你好,小红!
# 2. 单个占位符(整数)
print("年龄:%d岁" % 20) # 输出:年龄:20 岁
# 3. 单个占位符(浮点数,保留 2 位小数)
print("成绩:%.2f分" % 95.123) # 输出:成绩:95.12 分
# 4. 多个占位符(必须用元组包裹)
name = "小李"
age = 19
score = 88.5
print("姓名:%s,年龄:%d,成绩:%.1f" % (name,age,score))
# 输出:姓名:小李,年龄:19,成绩:88.5
五、转义字符
转义字符是一种特殊的字符表示方式,以反斜杠(\)开头,后跟一个或多个字符,用来表示那些无法直接输入(比如换行、制表符)或有特殊含义(比如双引号、反斜杠本身)的字符,可以把它理解成给普通字符赋予"特殊身份",或者取消特殊字符的"特殊身份"。
(1)Python 中常用的转义字符
Python 中最常用的转义字符见表 8-18 所列。
表 8-18 常用的转义字符
| 转义字符 | 含义 | 示例代码 | 输出效果 |
|---|---|---|---|
| \n | 换行符 | print("Hello\nWorld") | Hello<br>World |
| \t | 制表符(相当于按 Tab 键) | print("姓名\t年龄\t性别") | 姓名 年龄 性别(有固定间距) |
| \" | 双引号(取消引号的特殊含义) | print("He said:/"I love Python\"") | He said:"I love Python" |
| \' | 单引号(取消引号的特殊含义) | print('He said:/'I love Python\'') | He said:'I love Python' |
| \\ | 反斜杠本身 | print("路径:C://Users//Python") | 路径:C:/Users/Python |
| \r | 回车符(覆盖当前行开头) | print("12345\rabc") | abc45(abc 覆盖了 123) |
| \b | 退格符(删除前一个字符) | print("Hello\bWorld") | HellWorld(删除了 o) |
| \f | 换页符(较少用) | print("Page1\fPage2") | Page1(换页)Page2 |
| \a | 响铃符(触发系统提示音) | print("\a") | 电脑发出"嘀"的提示音 |
# 1. 换行符和制表符
print("==== 换行 & 制表符 ====")
print("Python 基础\n\t-- 变量\n\t-- 转义字符\n\t-- 函数")
# 2. 引号转义 print("\n===== 引号转义 =====")
print('小明说:\"今天学了转义字符,很有用!\"')
print("小红说:\"我也是,终于懂了\\n的意思!\"")
# 3. 反斜杠和退格符
print("\n===== 反斜杠 & 退格符 =====")
print("文件路径:C://Program Files\\Python\\python.exe")
print("123456\b\b789") # 退格两次,删除 5 和 6,输出 1234789
(2)取消转义(原始字符串)
如果不想让 Python 解析转义字符,那么可以在字符串前加 r 或 R,用于表示原始字符串。
# 原始字符串:\n 不会被解析为换行,而是直接显示\n
print(r"原始字符串:Hello\nWorld") # 输出:原始字符串:Hello\nWorld
print("普通字符串:Hello\nWorld") # 输出:普通字符串:Hello
# World
六、字符串的常用方法
字符串方法是 Python 为字符串类型内置的一系列预设函数,专门用于对字符串进行各种高效、标准化的操作,即无须从零编写复杂逻辑,直接调用这些方法就能完成对字符串的处理。
1. 大小写转换
大小写转换的方法见表 8-19 所列。
表 8-19 大小写转换的方法
| 方法 | 作用 | 示例 |
|---|---|---|
| upper() | 全部转为大写 | 'python'.upper()→'PYTHON' |
| lower() | 全部转为小写 | 'PYTHON'.lower()→'python' |
| capitalize() | 首字母大写,其余小写 | 'python is fun'.capitalize()→'Python is fun' |
| title() | 每个单词的首字母大写 | 'python is fun'.title()→'Python Is Fun' |
| swapcase() | 大小写互换 | 'Python'.swapcase()→'pYTHON' |
s = "Hello Python"
print("转大写:",s.upper()) # HELLO PYTHON
print("转小写:",s.lower()) # hello python
print("首字母大写:",s.capitalize()) # Hello python
print("每个单词首字母大写:",s.title()) # Hello Python
2. 查找与替换
查找与替换的方法见表 8-20 所列。
表 8-20 查找与替换的方法
| 方法 | 作用 | 示例 |
|---|---|---|
| find(sub) | 查找子串,返回首次出现的索引,找不到返回-1 | 'abcabc'.find('bc')→1 |
| index(sub) | 与 find 类似,但找不到会报错 | 'abc'.index('d')→报错 |
| count(sub) | 统计子串的出现次数 | 'abcabc'.count('ab')→2 |
| replace(old,new[,count]) | 替换子串,count 指定替换次数(可选) | 'aaa'.replace('a','b',2)→'bba' |
| rfind(sub) | 从右侧开始查找子串 | 'abcabc'.rfind('bc')→4 |
s = "今天天气真好,今天适合学习"
# 查找
print("'今天'首次出现位置:",s.find("今天")) # 0
print("'明天'是否存在:",s.find("明天")) # -1
# 统计
print("'今天'出现次数:",s.count("今天")) # 2
# 替换
print("替换所有'今天':",s.replace("今天","明天"))
# 明天天气真好,明天适合学习
print("只替换 1 次'今天':",s.replace("今天","明天",1))
# 明天天气真好,今天适合学习
3. 去除空白/指定字符
去除空白或指定字符的方法见表 8-21 所列。
表 8-21 去除空白或指定字符的方法
| 方法 | 作用 | 示例 |
|---|---|---|
| strip() | 去除首尾空白(空格、\n、\t、\r)或指定字符 | ' abc '.strip()→'abc';'## abc ## #'.strip('#')→'abc' |
| lstrip() | 去除左侧空白/指定字符 | ' abc '.lstrip()→'abc ' |
| rstrip() | 去除右侧空白/指定字符 | ' abc '.rstrip()→' abc' |
# 处理用户输入的空白
user_input = " 123456 \n"
clean_input = user_input.strip()
print("原始输入:",repr(user_input)) # ' 123456 \n'
print("清理后:",repr(clean_input)) # '123456'
# 去除指定字符
code = "# # # PYTHON # # #"
print(code.strip('#')) # PYTHON
print(code.lstrip('#')) # PYTHON # # #
4. 分割与拼接
字符串分割与拼接的方法见表 8-22 所列。
表 8-22 字符串分割与拼接的方法
| 方法 | 作用 | 示例 |
|---|---|---|
| split(sep=None, maxsplit=-1) | 按分隔符分割字符串为列表,maxsplit 指定分割次数 | 'a,b,c'.split(',')→['a','b','c'];'a,b,c'.split(',',1)→['a','b,c'] |
| rsplit() | 从右侧开始分割 | 'a,b,c'.rsplit(',',1)→['a,b','c'] |
| join(iterable) | 用字符串拼接可迭代对象(列表/元组等) | ','.join(['a','b','c'])→'a,b,c' |
| splitlines() | 按换行符分割,返回列表 | 'a\nb\nc'.splitlines()→['a','b','c'] |
# 分割
s = "苹果,香蕉,橙子,葡萄"
fruits = s.split(',')
print("分割后:",fruits) # ['苹果','香蕉','橙子','葡萄']
# 拼接(效率远高于用+拼接)
new_s = '|'.join(fruits)
print("拼接后:",new_s) # 苹果|香蕉|橙子|葡萄
# 按换行分割
text = "第一行\n 第二行\r 第三行"
print(text.splitlines()) # ['第一行',' 第二行',' 第三行']
5. 判断类方法
判断类方法见表 8-23 所列。
表 8-23 判断类方法
| 方法 | 作用 | 示例 |
|---|---|---|
| startswith(prefix) | 判断是否以指定前缀开头 | 'python'.startswith('py')→True |
| endswith(suffix) | 判断是否以指定后缀结尾 | 'test.txt'.endswith('.txt')→True |
| isalpha() | 判断是否全为字母 | 'Python'.isalpha()→True;'Python123'.isalpha()→False |
| isdigit() | 判断是否全为数字 | '12345'.isdigit()→True;'123a'.isdigit()→False |
| isalnum() | 判断是否由字母和数字组成 | 'Python123'.isalnum()→True |
| isspace() | 判断是否全为空白字符 | ' \t\n'.isspace()→True |
| islower()/isupper() | 判断是否全为小写/大写 | 'python'.islower()→True |
# 验证手机号(简单示例)
phone = "13812345678"
if phone.isdigit() and len(phone) == 11:
print("手机号格式正确")
else:
print("手机号格式错误")