摘要:本文全面讲解Python字符串的核心概念与实用技巧,涵盖字符串表示方式、转义字符、索引切片操作,以及三种字符串格式化方法(%格式化、format()方法和f-string)。通过详细的代码示例和对比分析,帮助读者掌握字符串处理的精髓。最后提供两个实战练习:个人名片制作和购物小票格式化,将理论知识转化为实际应用能力。
1. 字符串
字符串是 Python 中最常用的数据类型,用引号包裹。它的核心特点是不可变(一旦创建,就不能修改单个字符)。
1.1 字符串的表示方式
- 单引号/双引号:等价,但可在单引号内包含双引号,反之亦然。
- 三引号:用于多行字符串或文档注释。
- 转义字符:以反斜杠
\开头,用于表示那些无法直接输入或有特殊含义的字符。
| 转义字符 | 含义 | 示例 |
|---|---|---|
\\ | 反斜杠本身 | print('C:\\Users\\name') → C:\Users\name |
\' | 单引号 | print('I\'m OK') → I'm OK |
\" | 双引号 | print("He said \"Hi\"") → He said "Hi" |
\n | 换行符(LF) | print('a\nb') → a 换行 b |
\r | 回车符(CR) | print('a\rb') → b(覆盖 a) |
\t | 水平制表符(Tab) | print('a\tb') → a b(4个空格宽度) |
\v | 垂直制表符 | print('a\vb') → 垂直方向换行 |
\f | 换页符 | 一般用于打印机控制 |
\b | 退格键(Backspace) | print('abc\bd') → abd(c 被删除) |
\0 | 空字符(NULL) | print('a\0b') → a b(中间为空字符) |
\xhh | 十六进制字符 | print('\x48\x69') → Hi(\x48 是 H) |
\ooo | 八进制字符 | print('\110\151') → Hi(\110 是 H) |
\N{name} | Unicode 字符名 | print('\N{SNOWMAN}') → ☃ |
特别注意 \r 和 \n 的历史渊源:
- 在 Unix/Linux/macOS 系统中,换行用
\n。 - 在 Windows 系统中,换行用
\r\n(回车+换行)。 - 当你用 Python 读取 Windows 下的文本文件时,
\r\n会被自动转换为\n,所以一般不用太操心。
示例:转义字符的使用效果
# 常用转义
print("Hello\nWorld") # Hello 换行 World
print("Name\tAge\tCity") # Name Age City(Tab 对齐)
print("C:\\Users\\name") # 输出一个反斜杠
# 字符串中含引号
print('I\'m a teacher') # I'm a teacher
print("He said \"Python is great\"") # He said "Python is great"
# 退格效果(\b 删除前一个字符)
print("abc\bd") # abd
# 十六进制与八进制
print("\x48\x65\x6c\x6c\x6f") # Hello
print("\110\145\154\154\157") # Hello
# Unicode 字符名
print("\N{SMILING FACE}") # 一个笑脸 ☺
原始字符串(r 前缀): 忽略转义字符,常用于文件路径:
path = r'C:\Users\name\Documents' # 反斜杠不再转义
path = r'C:\Users\name\Documents'
print(path) # C:\Users\name\Documents
# 唯一例外:字符串末尾不能是单个反斜杠
# r'C:\Users\' ❌ 错误
r'C:\Users\\' ✅ 正确
1.2 字符串操作符
| 操作 | 示例 | 结果 |
|---|---|---|
| 连接 | 'Hello' + ' ' + 'World' | 'Hello World' |
| 重复 | 'Hi' * 3 | 'HiHiHi' |
| 成员 | 'a' in 'abc' | True |
| 相邻字符串自动合并 | 'Py' 'thon' | 'Python' |
1.3 索引与切片 —— 精准提取子串
字符串是字符的有序序列,每个字符在序列中都有一个固定的位置(偏移量)。Python 通过索引和切片两种方式,帮我们从字符串中提取单个字符或一段子串。
1.3.1 索引(Index)—— 提取单个字符
索引就是字符在字符串中的位置编号。Python 提供了正向索引和负向索引两套编号系统:
例如,s = “0123456789”
正向索引:从左到右,从 0 开始递增。
| 字符 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| s = | ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’ |
负向索引:从右到左,从 -1 开始递减。
| 字符 | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
|---|---|---|---|---|---|---|---|---|---|---|
| s = | ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’ |
基本索引操作:
s = '0123456789'
# 正向索引
print(s[0]) # '0' —— 第1个字符
print(s[5]) # '5' —— 第6个字符
print(s[9]) # '9' —— 最后一个字符
# 负向索引
print(s[-1]) # '9' —— 最后一个字符
print(s[-5]) # '5' —— 倒数第5个字符
print(s[-10]) # '0' —— 第1个字符(注意正向0和负向-10对应同一位置)
⚠️ 索引越界错误:索引值不能超出有效范围,否则会触发 IndexError。
print(s[10]) # IndexError: string index out of range
print(s[-11]) # IndexError: string index out of range
特殊索引公式:
- 正向索引 i 对应的负向索引是 i - len(s)
- 例如:本例中
s[0]等价于s[-10],s[5]等价于s[-5]
1.3.2 切片(Slicing)—— 提取连续子串
切片可以从字符串中提取一段连续的子串,格式为:
s[start : end : step]
start:起始索引(包含该位置,默认为 0)end:结束索引(不包含该位置,默认为字符串长度)step:步长(每次移动几个位置,默认为 1)
基本原理:切片区间为 [start, end),即左闭右开。
① 基本切片(只指定 start 和 end)
s = '0123456789'
print(s[2:5]) # '234' —— 索引 2,3,4(不包含5)
print(s[1:8]) # '1234567' —— 索引 1 到 7
print(s[0:3]) # '012' —— 索引 0,1,2
② 省略 start 或 end
# 省略 start:从开头开始
print(s[:5]) # '01234' —— 等价于 s[0:5]
# 省略 end:一直取到末尾
print(s[5:]) # '56789' —— 等价于 s[5:10]
# 两端都省略:复制整个字符串
print(s[:]) # '0123456789'
③ 步长(step)参数
# 步长为正:从左到右取
print(s[0:9:2]) # '02468' —— 索引 0,2,4,6,8
print(s[1:8:3]) # '147' —— 索引 1,4,7
# 步长为负:从右到左取(反向)
print(s[8:1:-2]) # '8642' —— 索引 8,6,4,2
print(s[::-1]) # '9876543210' —— 反转字符串(最常用)
④ 巧妙使用负索引切片
# 从倒数第6个取到倒数第2个(不包含倒数第1个)
print(s[-6:-1]) # '45678'
# 取最后三个字符
print(s[-3:]) # '789'
# 从开头取到倒数第4个(不包含)
print(s[:-4]) # '012345'
⑤ 切片常见陷阱与注意事项
# 当 start 或 end 超出边界时,Python 会自动截断,不会报错
print(s[-100:5]) # '01234'(自动从0开始)
print(s[5:100]) # '56789'(自动到末尾)
# start 在 end 右边时,返回空字符串(步长为正数)
print(s[5:2]) # ''(空字符串)
print(s[5:2:-1]) # '543'(步长为负数,从5倒着取到3)
⑥ 切片的高级技巧
# 每隔一个字符取一个
s[::2] # '02468'
# 反向每隔一个取一个
s[::-2] # '97531'
# 取中间三个字符(长度10,从索引3开始,到索引6结束)
s[3:6] # '345'
# 动态获取中间索引(对于任意长度)
mid = len(s) // 2
print(s[mid-1:mid+2]) # 取中间3个字符
实战技巧:常用切片模板
| 目的 | 代码 | 示例(s=‘0123456789’) |
|---|---|---|
| 取前 n 个字符 | s[:n] | s[:3] → '012' |
| 取后 n 个字符 | s[-n:] | s[-3:] → '789' |
| 去掉前 n 个字符 | s[n:] | s[3:] → '3456789' |
| 去掉后 n 个字符 | s[:-n] | s[:-3] → '0123456' |
| 反转字符串 | s[::-1] | '9876543210' |
| 取每隔 n 个字符 | s[::n] | s[::2] → '02468' |
| 取中间一段 | s[a:b] | s[3:7] → '3456' |
2. 字符串格式化 —— 让输出更优雅
Python 提供了三种字符串格式化方式,从老到新依次是:
2.1 % 格式化(C 语言风格)
这是 Python 最早引入的格式化方式,语法和 C 语言的 printf 类似。
基本语法:
格式字符串 % (参数1, 参数2, ...)
示例:
name, age = 'Alice', 25
print('My name is %s, I am %d years old.' % (name, age))
# My name is Alice, I am 25 years old.
常用格式符:
| 格式符 | 含义 | 示例 |
|---|---|---|
%s | 字符串 | '%s' % 'hello' → 'hello' |
%d | 十进制整数 | '%d' % 123 → '123' |
%f | 浮点数 | '%f' % 3.14 → '3.140000' |
%.2f | 保留两位小数 | '%.2f' % 3.14159 → '3.14' |
%x / %X | 十六进制(小写/大写) | '%x' % 255 → 'ff' |
%o | 八进制 | '%o' % 255 → '377' |
%e / %E | 科学计数法 | '%e' % 12345 → '1.234500e+04' |
%r | 原始表示(带引号) | '%r' % 'hello' → "'hello'" |
%% | 输出百分号本身 | '%d%%' % 50 → '50%' |
对齐与补零:
num = 123
# 宽度控制(默认右对齐)
print('%6d' % num) # ' 123'(宽度6,右侧对齐,左侧补空格)
print('%-6d' % num) # '123 '(宽度6,左对齐)
print('%06d' % num) # '000123'(宽度6,右侧对齐,左侧补0)
# 显示正负号
print('%+d' % 123) # '+123'
print('%+d' % -123) # '-123'
注意: % 格式化在 Python 3.x 中依然可用,但在新项目中已不推荐使用,推荐使用更新的方式。
2.2 format() 方法(更强大)
Python 3.0 引入的格式化方法,功能比 % 更丰富,可读性也更好。
基本用法:
# 按位置参数(默认顺序)
print('{} + {} = {}'.format(1, 2, 3)) # '1 + 2 = 3'
# 指定位置索引(可重复使用)
print('{0} + {1} = {2},{0} + {0} = {0}'.format(1, 2, 3)) # '1 + 2 = 3,1 + 1 = 1'
# 按关键字参数
print('{a} + {b} = {c}'.format(a=1, b=2, c=3)) # '1 + 2 = 3'
格式规格语法:
{ [字段名] [!转换] [:格式规格] }
格式规格详解:
# 1. 对齐与填充(默认左对齐字符串,右对齐数字)
print('{:<10}'.format('left')) # 'left '(左对齐,宽度10)
print('{:>10}'.format('right')) # ' right'(右对齐,宽度10)
print('{:^10}'.format('center')) # ' center '(居中对齐,宽度10)
print('{:*^10}'.format('center')) # '**center**'(用*填充)
# 2. 数字格式化
print('{:.2f}'.format(3.14159)) # '3.14'(保留两位小数)
print('{:.0f}'.format(3.9)) # '4'(四舍五入保留整数)
print('{:,}'.format(1234567)) # '1,234,567'(千位分隔符)
print('{:_}'.format(1234567)) # '1_234_567'(下划线分隔)
# 3. 进制转换
print('{:b}'.format(255)) # '11111111'(二进制)
print('{:o}'.format(255)) # '377'(八进制)
print('{:x}'.format(255)) # 'ff'(十六进制,小写)
print('{:X}'.format(255)) # 'FF'(十六进制,大写)
# 4. 科学计数法与百分比
print('{:e}'.format(12345)) # '1.234500e+04'
print('{:.2%}'.format(0.1234)) # '12.34%'
从对象中提取属性(拓展):
# 从对象中提取属性
person = {'name': 'Alice', 'age': 25}
print('Name: {name}, Age: {age}'.format(**person)) # Name: Alice, Age: 25
# 从列表中提取元素
data = ['apple', 'banana', 'cherry']
print('First: {0[0]}, Last: {0[-1]}'.format(data)) # First: apple, Last: cherry
2.3 f-string(Python 3.6+,最推荐)
f-string(格式化字符串字面量)是 Python 3.6 引入的新特性,是目前最简洁、最易读、性能最好的格式化方式。
基本语法: 在字符串前加 f,用 {} 直接嵌入变量或表达式。
# 嵌入变量
name, age = 'Alice', 25
print(f'My name is {name}, I am {age} years old.')
# My name is Alice, I am 25 years old.
# 嵌入表达式
print(f'3 + 5 = {3 + 5}') # 3 + 5 = 8
print(f'{name.upper()} is {age * 2} years old') # ALICE is 50 years old
格式规格: 和 format() 的格式规格完全一致。
# 对齐与填充
name = 'center'
print(f'{name:<10}') # 'center '
print(f'{name:>10}') # ' center'
print(f'{name:^10}') # ' center '
print(f'{name:*^10}') # '**center**'
# 数字格式
pi = 3.14159
print(f'{pi:.2f}') # '3.14'
print(f'{pi:.0f}') # '3'
print(f'{1234567:,}') # '1,234,567'
# 进制转换
num = 255
print(f'{num:b}') # '11111111'(二进制)
print(f'{num:o}') # '377'(八进制)
print(f'{num:x}') # 'ff'(十六进制,小写)
print(f'{num:X}') # 'FF'(十六进制,大写)
print(f'{num:#b}') # '0b11111111'(带前缀)
print(f'{num:#x}') # '0xff'(带前缀)
注意: {} 中不能使用反斜杠(如 \n),但可以先将内容存到变量中。
# ❌ 错误
# print(f'{name\n}')
# ✅ 正确
newline = '\n'
print(f'Hello{newline}World')
三种格式化方式对比
| 方式 | 写法 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
% 格式化 | '%s' % name | 简单 | 可读性差,扩展性弱 | 不推荐新项目 |
format() | '{}'.format(name) | 功能强大 | 写法稍长 | 可用(Python 3.0+) |
f-string | f'{name}' | 简洁直观,性能最好 | 需要 Python 3.6+ | 强烈推荐 |
建议: 新项目优先使用 f-string,代码更简洁;如果需要兼容 Python 3.5 及以下版本,使用 format()。
实战练兵场(代码练习)
理论看再多,不如动手敲一行。
练习1:创建个人名片
创建一个Python程序,用不同的字符串方式制作一张个人信息名片。
要求:
(1)使用单引号创建姓名变量
(2)使用双引号创建个性签名(签名中包含单引号)
(3)使用三引号创建个人简介(至少2行)
(4)使用原始字符串创建文件路径(例如:C:\Users\你的名字\Documents)
(5)输出名片
输出格式:

参考代码:
print('='*40)
print("个人名片")
print('='*40)
# (1)使用单引号创建姓名变量
name = 'orange'
# (2)使用双引号创建个性签名(签名中包含单引号)
signature = "代码改变世界,编程创造未来'python'"
# (3)使用三引号创建个人简介(至少2行)
introduction = """
热爱编程的大一学生
梦想成为python高手
学习目标:掌握字符串所有方法
"""
# (4)使用原始字符串创建文件路径(例如:C:\Users\你的名字\Documents)
file_path = r"E:\code\pythonclass\identify_card.py"
print('姓名:'+name)
print('签名:'+ signature)
print('=' * 40)
print('个人简介:')
print(introduction)
print('=' * 40)
print('文件路径:', file_path)
print('=' * 40)
练习2:购物小票格式化
你开了一家小超市,需要为顾客打印整齐的购物小票。完成小票格式化代码,使输出对齐美观。
要求:
| 商品1 | 商品2 | 商品3 |
|---|---|---|
product1 = "苹果" | product2 = "牛奶" | product3 = "面包" |
price1 = 6.5 | price2 = 12.0 | price3 = 8.5 |
qty1 = 2 | qty2 = 1 | qty3 = 3 |
subtotal1 = price1 * qty1 | subtotal2 = price2 * qty2 | subtotal3 = price3 * qty3 |
打印表格表头:商品名左对齐,宽度10;单价右对齐,宽度8;数量右对齐,宽度6;小计右对齐,宽度8。
打印商品信息:商品名左对齐,宽度10;单价右对齐,宽度8,保留1位小数;数量右对齐,宽度6;小计右对齐,宽度8,保留1位小数。
输出格式:
参考代码:
print('=' * 38)
# 居中对齐打印标题,宽度38个字符 {:^38} 表示居中对齐,宽度为38
print("{:^38}".format("快乐超市"))
print('=' * 38)
product1 = "苹果" # 商品名称(字符串)
price1 = 6.5 # 单价(浮点数)
qty1 = 2 # 数量(整数)
subtotal1 = price1 * qty1 # 小计 = 单价 × 数量
product2 = "牛奶" # 商品名称
price2 = 12.0 # 单价
qty2 = 1 # 数量
subtotal2 = price2 * qty2 # 小计
product3 = "面包" # 商品名称
price3 = 8.5 # 单价
qty3 = 3 # 数量
subtotal3 = price3 * qty3 # 小计
# ========== 打印表格表头 ==========
# {:<10} 左对齐,宽度10(商品名)
# {:>8} 右对齐,宽度8(单价)
# {:>6} 右对齐,宽度6(数量)
# {:>8} 右对齐,宽度8(小计)
print("{:<10} {:>8} {:>6} {:>8}".format("商品", "单价", "数量", "小计"))
print('-' * 38)
# ========== 打印商品信息 ==========
# {:<10} 商品名左对齐,宽度10
# {:>8.1f} 单价右对齐,宽度8,保留1位小数(f表示浮点数)
# {:>6} 数量右对齐,宽度6
# {:>8.1f} 小计右对齐,宽度8,保留1位小数
line1 = "{:<10} {:>8.1f} {:>6} {:>8.1f}".format(product1, price1, qty1, subtotal1)
print(line1)
line2 = "{:<10} {:>8.1f} {:>6} {:>8.1f}".format(product2, price2, qty2, subtotal2)
print(line2)
line3 = "{:<10} {:>8.1f} {:>6} {:>8.1f}".format(product3, price3, qty3, subtotal3)
print(line3)
print("-" * 38)
total = subtotal1 + subtotal2 + subtotal3
# ========== 打印总金额 ==========
# {:*^38} 居中对齐,宽度40,两边用星号(*)填充
# 注意:format()里面又嵌套了一个format(),先计算内层的,再计算外层的
# 内层:"总计:{:.1f}元".format(total) → 得到字符串"总计:50.5元"
# 外层:将得到的字符串居中,两边用*填充
print("{:*^38}".format("总计:{:.1f}元".format(total)))
# ========== 付款信息 ==========
cash = 50 # 实收金额(顾客付的钱)
change = cash - total # 找零 = 实收 - 总计
print("实收:{}元".format(cash)) # 打印实收金额(原样输出,不做特殊格式)
print("找零:{:.1f}元".format(change)) # 打印找零,保留1位小数
print("=" * 38) # 打印底部装饰线
print("{:^38}".format("欢迎下次光临!")) # 打印结束语,居中对齐
&spm=1001.2101.3001.5002&articleId=162057602&d=1&t=3&u=03943a9570d440e0827ec23569dab574)
17万+

被折叠的 条评论
为什么被折叠?



