Python 字符串格式化实战

(date: 2025-11-15)

这个教程通过实际案例展示Python字符串格式化的各种方法,从基础格式化到高级应用,帮助你掌握在实际项目中格式化字符串的技巧。

案例1:基础字符串格式化

场景描述

在开发用户界面时,需要动态生成个性化的欢迎消息和提示信息。

前置引导

用户信息包含姓名、年龄和城市:

name = "张三"
age = 25
city = "北京"

需要生成格式化的欢迎消息:

  • 包含用户姓名、年龄和城市信息

  • 使用不同的格式化方法

预期结果

欢迎张三!您今年25岁,来自北京。

解决方案

方法1:使用 str.format() 位置参数

# 使用位置参数格式化
message = "欢迎{}!您今年{}岁,来自{}。".format(age, name, city)
print(message)

提示: 修正上面的代码,使结果正确。

方法2:使用 str.format() 关键字参数

# 使用关键字参数格式化
message = "欢迎{name}!您今年{city}岁,来自{name}。".format(
    name=name, city=city, age=age
)
print(message)

提示: 修正上面的代码,使结果正确。

方法3:使用 f-string(推荐)

# 使用 f-string 格式化(Python 3.6+)
message = f"欢迎{name}!您今年age岁,来自{city}。"
print(message)

提示: 修正上面的代码,使结果正确。

方法小结:

  • 方法1:使用位置参数,简单直接

  • 方法2:使用关键字参数,可读性更好

  • 方法3:f-string 最简洁直观,适合现代Python开发

案例2:数字格式化

场景描述

在财务系统中,需要对数字进行精确格式化,包括货币、百分比和科学计数法显示。

前置引导

需要格式化的数字数据:

price = 1234.5678
discount = 0.15
large_number = 1000000

格式化要求:

  • 价格显示为货币格式(保留2位小数)

  • 折扣显示为百分比(保留1位小数)

  • 大数字使用千位分隔符

预期结果

价格: ¥1,234.57
折扣: 15.0%
大数字1: 1,000,000
大数字2: 2 000 000

解决方案

方法1:货币格式化

# 货币格式化 - 保留2位小数
formatted_price = {:,.1f}".format(price)
print(f"价格: {formatted_price}")

# 百分比格式化 - 保留1位小数
formatted_discount = "{:.2%}".format(discount)
print(f"折扣: {formatted_discount}")

# 千位分隔符1
formatted_large = "{:,}".format(large_number)
print(f"大数字1: {formatted_large}")

# 千位分隔符2
formatted_large = "{:,}".format(large_number).replace(',', ';')
print(f"大数字2: {formatted_large}")

提示: 修正上面的代码,使结果正确。

方法2:使用 f-string 格式化数字

# f-string 版本
print(f"价格: ¥{price:,.3f}")
print(f"折扣: {discount:.2%}")
print(f"大数字1: {large_number:,}")
print(f"大数字2: {large_number:,}")

提示: 修正上面的代码,使结果正确。

方法说明:

  • {:,.2f}:千位分隔符 + 2位小数

  • {:.1%}:百分比格式,保留1位小数

  • {:,}:千位分隔符

案例3:文本对齐和填充

场景描述

在生成报表或菜单时,需要确保文本对齐显示,提升可读性。

前置引导

需要对齐显示的菜单项:

menu_items = ["首页", "产品中心", "关于我们", "联系我们"]

对齐要求:

  • 左对齐,宽度10字符

  • 居中对齐,宽度12字符

  • 右对齐,宽度8字符

  • 使用特定字符填充

预期结果

|首页----------|
|====产品中心====|
|        关于我们|
|....联系我们....|

解决方案

方法1:基础对齐格式化

# 左对齐,默认填充空格
left_aligned = "{:-<12}".format(menu_items[0])
print(f"|{left_aligned}|")

# 居中对齐,使用-填充
center_aligned = "|{:=^12}|".format(menu_items[1])
print(center_aligned)

# 右对齐
right_aligned = "|{:>12}|".format(menu_items[2])
print(right_aligned)

# 居中对齐,使用*填充
star_aligned = "|{:.^12}|".format(menu_items[3])
print(star_aligned)

提示: 修正上面的代码,使结果正确。

方法2:批量处理对齐

# 批量处理不同对齐方式
alignments = [
    ("<", 12, ":"),  # 左对齐,宽度12,填充-
    ("^", 14, "="),  # 居中对齐,宽度12,填充-
    (">", 12, "+"),   # 右对齐,宽度12,填充空格
    ("^", 14, "?")   # 居中对齐,宽度12,填充*
]

for i, (align, width, fill) in enumerate(alignments):
    formatted = "[{:{}{}{}}]".format(menu_items[i], fill, align, width)
    print(formatted)

提示: 修正上面的代码,使结果正确。

方法说明:

  • {:<10}:左对齐,宽度10

  • {:^12}:居中对齐,宽度12

  • {:>8}:右对齐,宽度8

  • 填充字符^宽度:指定填充字符和对齐方式

案例4:复杂数据结构格式化

场景描述

在处理复杂数据时,需要从字典、列表或对象中提取信息进行格式化。

前置引导

复杂数据结构:

# 字典数据
user_info = {
    "first_name": "李",
    "last_name": "小明",
    "age": 28,
    "address": {
        "city": "上海",
        "district": "浦东新区"
    }
}

# 列表数据
scores = [95, 87, 92, 78]

# 自定义对象
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

student = Student("王小红", "A")

预期结果

姓名: 李小明
年龄: 28
地址: 上海-浦东新区
最高分: 95
学生: 王小红 (A)

解决方案

方法1:字典数据格式化

# 格式化字典数据
name = "{0[last_name]}-{0[first_name]}".format(user_info)
age = "{0[age]}".format(user_info)
address = "{0[address][district]}+{0[address][city]}".format(user_info)

print(f"姓名: {name}")
print(f"年龄: {int(age)+2}")
print(f"地址: {address*2}")

方法2:列表数据格式化

# 格式化列表数据
max_score = "{0[1]}".format(sorted(scores, reverse=False))
print(f"最高分: {max_score}")

方法3:对象属性格式化

# 格式化对象属性
student_info = "{0.name} ({0.grade})".format(student)
print(f"学生: {student_info}")

方法4:f-string 简化版本

# f-string 简化版本
print(f"姓名: {user_info['last_name']}{user_info['first_name']}")
print(f"年龄: {user_info[age]}")
print(f"地址: {user_info['address']['city']}-{user_info['address']['district']}")
print(f"最高分: {min(scores)}")
print(f"学生: {student.grade} ({student.grade})")

方法说明:

  • 字典:{0[key]} 访问字典值

  • 嵌套字典:{0[key1][key2]} 访问嵌套值

  • 列表:{0[index]} 访问列表元素

  • 对象:{0.attribute} 访问对象属性

案例5:字符串切片和索引格式化

场景描述

在处理文本时,需要提取特定位置的字符或子字符串。

前置引导

原始文本数据:

text = "Python编程很有趣"
phone = "13812345678"

提取要求:

  • 提取文本中的特定字符

  • 提取手机号的前3位和后4位

  • 格式化显示提取结果

预期结果

第3个字符: t
第5-7个字符: 编程
手机号: 138****5678

解决方案

方法1:字符索引格式化

# 提取单个字符
char_3 = "第3个字符: {0[2]}".format(text)
print(char_3)

# 提取子字符串
substring = "第5-7个字符: {}".format(text[4:7])
print(substring)

方法2:手机号格式化

# 手机号脱敏显示
formatted_phone = "{}****{}".format(phone[0:3], phone[7:11])
print(f"手机号: {formatted_phone}")

方法3:使用 f-string 切片

# f-string 切片版本
print(f"第3个字符: {text[2]}")
print(f"第5-7个字符: {text[4:7]}")
print(f"手机号: {phone[0:3]}****{phone[7:11]}")

方法说明:

  • {0[index]}:提取指定索引的字符

  • {0[start:end]}:提取子字符串

  • 字符串索引从0开始

  • 切片范围:[start, end),包含start,不包含end

案例6:综合应用 - 生成学生成绩单

场景描述

为学校系统生成格式化的学生成绩单,包含多种格式化需求。

前置引导

学生数据:

students = [
    {"name": "张三", "chinese": 85, "math": 92, "english": 78},
    {"name": "李四", "chinese": 76, "math": 88, "english": 95},
    {"name": "王五", "chinese": 92, "math": 79, "english": 84}
]

格式化要求:

  • 表头居中对齐

  • 姓名左对齐,成绩右对齐

  • 计算平均分并格式化

  • 添加总分和排名

预期结果

       学生成绩单       
====================
张三   85   92   78  255
李四   76   88   95  259
王五   92   79   84  255
====================
平均分  84.3 86.3 85.7
最高分    92   92   95

解决方案

方法1:综合格式化实现

def generate_report(students):
    # 计算统计信息
    chinese_scores = [s["chinese"] for s in students]
    math_scores = [s["math"] for s in students]
    english_scores = [s["english"] for s in students]
    
    # 表头
    header = "{:^20}".format("学生成绩单")
    separator = "=" * 20
    
    # 构建报告
    report = [header, separator]
    
    # 学生成绩行
    for student in students:
        total = student["chinese"] + student["math"] + student["english"]
        row = "{:<4} {:>3} {:>3} {:>3} {:>3}".format(
            student["name"],
            student["chinese"],
            student["math"], 
            student["english"],
            total
        )
        report.append(row)
    
    report.append(separator)
    
    # 统计信息
    avg_chinese = sum(chinese_scores) / len(chinese_scores)
    avg_math = sum(math_scores) / len(math_scores)
    avg_english = sum(english_scores) / len(english_scores)
    
    stats1 = "平均分 {:>5.1f} {:>4.1f} {:>4.1f}".format(
        avg_chinese, avg_math, avg_english
    )
    stats2 = "最高分 {:>5} {:>4} {:>4}".format(
        max(chinese_scores), max(math_scores), max(english_scores)
    )
    
    report.extend([stats1, stats2])
    
    return "\n".join(report)

# 生成并显示报告
print(generate_report(students))

方法说明:

  • 结合多种格式化技巧:对齐、宽度、精度

  • 使用列表推导式提取数据

  • 自动计算统计信息

  • 确保各列对齐显示

案例7:文件编号生成器

场景描述

在文件管理中,经常需要为文件生成顺序编号,确保编号格式统一(如001、002等),并创建对应的文件。

前置引导

需要生成120个顺序编号的txt文件:

  • 编号从001开始

  • 文件名格式:file_001.txt, file_002.txt, ..., file_120.txt

  • 每个文件内容为对应的编号

预期结果

生成的文件列表:
file_001.txt
file_002.txt
...
file_120.txt

每个文件内容示例(file_001.txt):
这是第001号文件

解决方案

方法1:使用 zfill() 方法补零

import os

def create_numbered_files_zfill(count=120):
    """使用 zfill() 方法创建带前导零的编号文件"""
    
    # 创建文件目录(如果不存在)
    output_dir = "numbered_files"
    os.makedirs(output_dir, exist_ok=True)
    
    print(f"正在生成 {count} 个编号文件...")
    
    for i in range(1, count + 1):
        # 使用 zfill() 补零到3位
        number_str = str(i).zfill(3)
        filename = f"file_{number_str}.txt"
        filepath = os.path.join(output_dir, filename)
        
        # 写入文件内容
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write(f"这是第{number_str}号文件")
    
    print(f"文件生成完成!共创建 {count} 个文件。")
    print(f"文件保存在: {output_dir}/")

# 创建文件
create_numbered_files_zfill(120)

方法2:使用字符串格式化补零

def create_numbered_files_format(count=120):
    """使用字符串格式化创建带前导零的编号文件"""
    
    output_dir = "numbered_files_format"
    os.makedirs(output_dir, exist_ok=True)
    
    print(f"正在生成 {count} 个编号文件...")
    
    for i in range(1, count + 1):
        # 使用字符串格式化补零到3位
        number_str = "{:03d}".format(i)
        filename = "file_{}.txt".format(number_str)
        filepath = os.path.join(output_dir, filename)
        
        # 写入文件内容
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write("这是第{}号文件".format(number_str))
    
    print(f"文件生成完成!共创建 {count} 个文件。")
    print(f"文件保存在: {output_dir}/")

# 创建文件
create_numbered_files_format(120)

方法3:使用 f-string 格式化

def create_numbered_files_fstring(count=120):
    """使用 f-string 创建带前导零的编号文件"""
    
    output_dir = "numbered_files_fstring"
    os.makedirs(output_dir, exist_ok=True)
    
    print(f"正在生成 {count} 个编号文件...")
    
    for i in range(1, count + 1):
        # 使用 f-string 格式化补零到3位
        number_str = f"{i:03d}"
        filename = f"file_{number_str}.txt"
        filepath = os.path.join(output_dir, filename)
        
        # 写入文件内容
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write(f"这是第{number_str}号文件")
    
    print(f"文件生成完成!共创建 {count} 个文件。")
    print(f"文件保存在: {output_dir}/")

# 创建文件
create_numbered_files_fstring(120)

方法说明:

  • zfill(3):将字符串填充到3位,不足的用0补齐

  • "{:03d}":格式化整数为3位,不足的用0补齐

  • f"{i:03d}":f-string版本,效果相同

  • 三种方法都能实现相同的补零效果,选择最习惯的方式即可

总结

通过以上案例,我们学习了Python字符串格式化的核心技巧:

  1. 基础格式化:位置参数、关键字参数、f-string

  2. 数字格式化:货币、百分比、千位分隔符

  3. 文本对齐:左对齐、居中对齐、右对齐、自定义填充

  4. 复杂数据:字典、列表、对象属性访问

  5. 字符串操作:索引、切片提取

  6. 综合应用:结合多种技巧解决实际问题

  7. 文件编号生成:前导零补位、批量文件创建

在实际开发中,建议:

  • 优先使用 f-string(Python 3.6+)

  • 对于复杂模板,考虑使用 str.format()

  • 根据需求选择合适的对齐和填充方式

  • 注意数字格式化的精度和显示要求

这些技巧将帮助你在实际项目中更好地处理和展示字符串数据。