【Python】Python字符串格式化
Python字符串格式化完全指南:从基础到高级实战
1. 引言:为什么需要字符串格式化?
在日常编程中,我们经常需要将各种数据类型转换为美观、易读的字符串形式。无论是生成报告、日志记录还是用户界面显示,字符串格式化都是不可或缺的技能。Python提供了多种强大的字符串格式化方法,每种方法都有其适用场景。
格式化的重要性:
- 提高代码可读性
- 生成专业的数据展示
- 便于调试和日志记录
- 提升用户体验
2. f-string:现代Python的首选
2.1 基础语法与示例
f-string(格式化字符串字面值)是Python 3.6引入的特性,以其简洁的语法和优秀的性能成为现代Python开发的首选。
# 基本语法
name = "张三"
age = 25
print(f"姓名:{name},年龄:{age}")# 浮点数格式化
pi = 3.1415926
print(f"圆周率:{pi:.2f}") # 保留2位小数
2.2 f-string浮点数格式化完整参考表
| 格式说明符 | 描述 | 示例代码 | 输出结果 |
|---|---|---|---|
:.0f | 保留0位小数 | f"{3.1415:.0f}" | 3 |
:.1f | 保留1位小数 | f"{3.1415:.1f}" | 3.1 |
:.2f | 保留2位小数 | f"{3.1415:.2f}" | 3.14 |
:.3f | 保留3位小数 | f"{3.1415:.3f}" | 3.142 |
:.4f | 保留4位小数 | f"{3.1415:.4f}" | 3.1415 |
:.5f | 保留5位小数 | f"{3.1415:.5f}" | 3.14150 |
2.3 宽度控制与对齐方式
number = 12.3456# 宽度控制示例
print(f"|{number:.2f}|") # 默认
print(f"|{number:10.2f}|") # 宽度10
print(f"|{number:<10.2f}|") # 左对齐
print(f"|{number:>10.2f}|") # 右对齐
print(f"|{number:^10.2f}|") # 居中对齐
2.4 宽度与对齐格式化选项表
| 格式说明符 | 描述 | 示例代码 | 输出结果 |
|---|---|---|---|
:10.2f | 宽度10,保留2位 | f"|{12.3456:10.2f}|" | | 12.35| |
:<10.2f | 左对齐,宽度10 | f"|{12.3456:<10.2f}|" | |12.35 | |
:>10.2f | 右对齐,宽度10 | f"|{12.3456:>10.2f}|" | | 12.35| |
:^10.2f | 居中对齐,宽度10 | f"|{12.3456:^10.2f}|" | | 12.35 | |
:*^10.2f | 居中对齐,填充* | f"{12.3456:*^10.2f}" | ***12.35*** |
:0>10.2f | 右对齐,填充0 | f"{12.3456:0>10.2f}" | 0000012.35 |
2.5 符号显示控制
positive = 12.34
negative = -12.34print(f"正数: {positive:+.2f}") # +12.34
print(f"负数: {negative:+.2f}") # -12.34
print(f"正数: {positive:-.2f}") # 12.34
print(f"负数: {negative:-.2f}") # -12.34
print(f"空格: {positive: .2f}") # 12.34
2.6 符号显示格式化选项表
| 格式说明符 | 描述 | 示例代码 | 输出结果 |
|---|---|---|---|
:+.2f | 总是显示符号 | f"{12.34:+.2f}" | +12.34 |
:-.2f | 仅负数显示符号 | f"{12.34:-.2f}" | 12.34 |
: .2f | 正数前加空格 | f"{12.34: .2f}" | 12.34 |
:+.0f | 整数显示符号 | f"{12:+.0f}" | +12 |
2.7 高级f-string特性
# 表达式计算
a, b = 5, 3
print(f"{a} + {b} = {a + b}") # 5 + 3 = 8# 调用函数
name = "python"
print(f"大写: {name.upper()}") # 大写: PYTHON# 字典访问
person = {"name": "李四", "age": 30}
print(f"姓名: {person['name']}, 年龄: {person['age']}")# 条件表达式
score = 85
print(f"成绩: {score},等级: {'优秀' if score >= 90 else '良好' if score >= 80 else '及格'}")
3. format()方法:功能强大的传统方式
3.1 基础用法
format()方法是Python 2.6引入的字符串格式化方法,功能全面且灵活。
# 基本用法
name = "王五"
age = 28
print("姓名:{},年龄:{}".format(name, age))# 位置参数
print("{0}的{1}成绩是{2}分".format("小明", "数学", 95))# 关键字参数
print("坐标:({x}, {y})".format(x=10, y=20))
3.2 format()浮点数格式化表
| 格式说明符 | 描述 | 示例代码 | 输出结果 |
|---|---|---|---|
{:.2f} | 保留2位小数 | "{:.2f}".format(3.1415) | 3.14 |
{:+.2f} | 显示符号 | "{:+.2f}".format(3.1415) | +3.14 |
{:10.2f} | 宽度10 | "|{:10.2f}|".format(12.345) | | 12.35| |
{:<10.2f} | 左对齐 | "|{:<10.2f}|".format(12.345) | |12.35 | |
{:0>10.2f} | 填充0 | "{:0>10.2f}".format(12.345) | 0000012.35 |
3.3 高级format()用法
# 对齐和填充
print("{:*^20}".format("居中标题")) # ******居中标题******# 数字格式化
print("十进制: {0:d}, 十六进制: {0:x}, 八进制: {0:o}, 二进制: {0:b}".format(42))# 千位分隔符
print("{:,}".format(123456789)) # 123,456,789# 百分比
print("{:.2%}".format(0.875)) # 87.50%
4. %操作符:经典的格式化方法
4.1 基础语法
%操作符是Python最传统的字符串格式化方法,虽然不推荐在新项目中使用,但在维护旧代码时仍会见到。
# 基本用法
name = "赵六"
age = 35
print("姓名:%s,年龄:%d" % (name, age))# 浮点数格式化
pi = 3.1415926
print("圆周率:%.2f" % pi)
4.2 %格式化选项表
| 格式说明符 | 描述 | 示例代码 | 输出结果 |
|---|---|---|---|
%.2f | 保留2位小数 | "%.2f" % 3.1415 | 3.14 |
%+.2f | 显示符号 | "%+.2f" % 3.1415 | +3.14 |
%10.2f | 宽度10 | "|%10.2f|" % 12.345 | | 12.35| |
%-10.2f | 左对齐 | "|%-10.2f|" % 12.345 | |12.35 | |
%d | 整数 | "%d" % 3.1415 | 3 |
%s | 字符串 | "%s" % 3.1415 | 3.1415 |
4.3 常用%格式化符号表
| 格式符 | 描述 | 示例 |
|---|---|---|
%s | 字符串 | "%s" % "hello" |
%d | 十进制整数 | "%d" % 42 |
%f | 浮点数 | "%f" % 3.14 |
%x | 十六进制整数 | "%x" % 255 |
%o | 八进制整数 | "%o" % 64 |
%e | 科学计数法 | "%e" % 1000 |
5. 数字格式化进阶
5.1 千位分隔符
# 千位分隔符示例
numbers = [1234, 1234567, 1234567890]print("千位分隔符格式化:")
for num in numbers:print(f"{num:,}") # f-string方式print("{:,}".format(num)) # format方式print("%d" % num) # %方式(不支持千位分隔符)
5.2 科学计数法
# 科学计数法格式化
small_numbers = [0.000123, 0.001234, 0.012345]
large_numbers = [1234567, 123456789, 12345678901]print("小数的科学计数法:")
for num in small_numbers:print(f"{num:.2e}")print("\n大数的科学计数法:")
for num in large_numbers:print(f"{num:.2e}")
5.3 科学计数法格式化表
| 格式说明符 | 描述 | 示例代码 | 输出结果 |
|---|---|---|---|
:.2e | 科学计数法,2位小数 | f"{0.000123456:.2e}" | 1.23e-04 |
:.3e | 科学计数法,3位小数 | f"{0.000123456:.3e}" | 1.235e-04 |
:+.2e | 带符号科学计数法 | f"{0.000123456:+.2e}" | +1.23e-04 |
:.2E | 大写E科学计数法 | f"{0.000123456:.2E}" | 1.23E-04 |
5.4 百分比格式化
# 百分比格式化
percentages = [0.1234, 0.5678, 0.9876, 1.2345]print("百分比格式化:")
for pct in percentages:print(f"{pct:.2%}") # f-string方式print("{:.2%}".format(pct)) # format方式print("%.2f%%" % (pct * 100)) # %方式
6. 四舍五入规则详解
6.1 银行家舍入法
Python使用"银行家舍入法"(round half to even),这种舍入方式可以减少统计偏差。
# 四舍五入测试案例
test_cases = [(1.234, 2), # 期望: 1.23(1.235, 2), # 期望: 1.24(1.236, 2), # 期望: 1.24(1.225, 2), # 特殊情况: 1.22(1.245, 2), # 1.24(2.675, 2), # 2.68(2.665, 2), # 2.66
]print("四舍五入规则测试:")
for num, precision in test_cases:formatted = f"{num:.{precision}f}"print(f"{num} -> {formatted}")
6.2 四舍五入规则详细表
| 原始值 | 舍入到2位 | 舍入规则说明 |
|---|---|---|
| 1.234 | 1.23 | 直接舍去(4小于5) |
| 1.235 | 1.24 | 五入(5等于5,前一位是奇数3) |
| 1.236 | 1.24 | 五入(6大于5) |
| 1.225 | 1.22 | 银行家舍入(5等于5,前一位是偶数2) |
| 1.245 | 1.24 | 银行家舍入(5等于5,前一位是偶数4) |
| 2.675 | 2.68 | 五入(5等于5,前一位是奇数7) |
| 2.665 | 2.66 | 银行家舍入(5等于5,前一位是偶数6) |
7. 实际应用场景
7.1 金融数据格式化
def format_financial_data():"""金融数据格式化示例"""# 股票价格数据stocks = [{"name": "AAPL", "price": 182.63, "change": 2.45, "change_percent": 1.36},{"name": "GOOGL", "price": 138.21, "change": -1.23, "change_percent": -0.88},{"name": "MSFT", "price": 337.29, "change": 5.67, "change_percent": 1.71},]print("股票行情:")print(f"{'名称':<8} {'价格':>10} {'涨跌':>10} {'涨幅':>10}")print("-" * 45)for stock in stocks:# 根据涨跌设置颜色标记(实际显示可能需要支持ANSI颜色的终端)change_color = "+" if stock["change"] >= 0 else ""percent_color = "+" if stock["change_percent"] >= 0 else ""print(f"{stock['name']:<8} "f"${stock['price']:>9.2f} "f"{change_color}{stock['change']:>9.2f} "f"{percent_color}{stock['change_percent']:>9.2f}%")def format_currency(amount, currency="CNY"):"""货币金额格式化"""symbols = {"CNY": "¥","USD": "$","EUR": "€","GBP": "£","JPY": "¥"}symbol = symbols.get(currency, currency)return f"{symbol}{amount:,.2f}"# 使用示例
format_financial_data()print("\n货币格式化示例:")
amounts = [1234.56, 7890.12, 45678.90, 123456.78]
for amount in amounts:print(f"人民币: {format_currency(amount)}, "f"美元: {format_currency(amount, 'USD')}")
7.2 科学数据报告
def format_scientific_report():"""科学数据报告格式化"""# 实验数据experiments = [{"name": "实验A", "value": 0.000123456, "uncertainty": 0.000000123},{"name": "实验B", "value": 1234.56789, "uncertainty": 12.34567},{"name": "实验C", "value": 9876543.21, "uncertainty": 9876.543},]print("科学实验数据报告:")print(f"{'实验名称':<12} {'测量值':>15} {'不确定度':>15} {'相对误差':>12}")print("-" * 60)for exp in experiments:# 根据数值大小选择合适的格式if abs(exp["value"]) < 0.001 or abs(exp["value"]) > 1000000:value_str = f"{exp['value']:.3e}"uncertainty_str = f"{exp['uncertainty']:.3e}"else:value_str = f"{exp['value']:,.3f}"uncertainty_str = f"{exp['uncertainty']:,.3f}"# 计算相对误差relative_error = abs(exp["uncertainty"] / exp["value"]) * 100print(f"{exp['name']:<12} {value_str:>15} {uncertainty_str:>15} {relative_error:>11.2f}%")def format_chemical_concentration(concentration, unit="mol/L"):"""化学浓度格式化"""if concentration < 0.000001:return f"{concentration:.2e} {unit}"elif concentration < 0.001:return f"{concentration * 1000000:.2f} μ{unit}"elif concentration < 1:return f"{concentration * 1000:.2f} m{unit}"else:return f"{concentration:.2f} {unit}"# 使用示例
format_scientific_report()print("\n化学浓度格式化示例:")
concentrations = [0.000000123, 0.000456, 0.789, 12.345]
for conc in concentrations:print(f"浓度: {format_chemical_concentration(conc)}")
7.3 表格数据生成
def generate_data_table():"""生成格式化的数据表格"""# 学生成绩数据students = [{"name": "张三", "math": 95.5, "english": 88.0, "science": 92.3, "history": 85.7},{"name": "李四", "math": 87.2, "english": 91.5, "science": 89.8, "history": 93.1},{"name": "王五", "math": 78.9, "english": 82.4, "science": 76.5, "history": 79.8},{"name": "赵六", "math": 92.1, "english": 94.7, "science": 96.3, "history": 90.2},]# 表头headers = ["姓名", "数学", "英语", "科学", "历史", "平均分", "等级"]print("学生成绩表")print("=" * 70)# 打印表头header_line = " | ".join(f"{header:^8}" for header in headers)print(f"| {header_line} |")print("|" + "-" * 70 + "|")# 打印数据行for student in students:# 计算平均分scores = [student["math"], student["english"], student["science"], student["history"]]average = sum(scores) / len(scores)# 确定等级if average >= 90:grade = "优秀"elif average >= 80:grade = "良好"elif average >= 70:grade = "中等"elif average >= 60:grade = "及格"else:grade = "不及格"# 格式化输出name = f"{student['name']:^8}"math = f"{student['math']:>7.1f}"english = f"{student['english']:>7.1f}"science = f"{student['science']:>7.1f}"history = f"{student['history']:>7.1f}"avg = f"{average:>7.1f}"grade_str = f"{grade:^8}"data_line = " | ".join([name, math, english, science, history, avg, grade_str])print(f"| {data_line} |")print("=" * 70)# 生成表格
generate_data_table()
8. 性能比较与最佳实践
8.1 各种格式化方法性能对比
import timeitdef performance_comparison():"""各种格式化方法性能比较"""# 测试数据name = "测试用户"value = 1234.56789count = 10000# f-string性能测试f_string_time = timeit.timeit(lambda: f"姓名:{name},数值:{value:.2f}",number=count)# format()性能测试format_time = timeit.timeit(lambda: "姓名:{},数值:{:.2f}".format(name, value),number=count)# %操作符性能测试percent_time = timeit.timeit(lambda: "姓名:%s,数值:%.2f" % (name, value),number=count)print("格式化方法性能比较(执行{}次):".format(count))print(f"f-string: {f_string_time:.5f}秒")print(f"format(): {format_time:.5f}秒")print(f"%操作符: {percent_time:.5f}秒")# 运行性能测试
performance_comparison()
8.2 格式化方法选择指南
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| Python 3.6+ 新项目 | f-string | 语法简洁,性能最优,可读性强 |
| 需要向后兼容 | format() | 功能强大,支持Python 2.6+ |
| 维护旧代码 | %操作符 | 保持代码一致性 |
| 复杂格式需求 | format() | 支持更复杂的格式化选项 |
| 性能敏感场景 | f-string | 执行速度最快 |
| 国际化项目 | format() | 更好的本地化支持 |
8.3 最佳实践总结
- 优先使用f-string:在新项目中使用f-string,享受其简洁语法和优秀性能
- 保持一致性:在同一个项目中保持格式化风格的一致性
- 考虑可读性:选择使代码更易读的格式化方式
- 处理边界情况:考虑数值为None或异常情况的处理
- 本地化考虑:国际化项目要考虑数字和日期格式的本地化差异
9. 完整实战示例
class FinancialReport:"""财务报表生成器"""def __init__(self, company_name, currency="CNY"):self.company_name = company_nameself.currency = currencyself.data = []def add_record(self, category, q1, q2, q3, q4):"""添加季度数据记录"""self.data.append({"category": category,"q1": q1, "q2": q2, "q3": q3, "q4": q4,"total": q1 + q2 + q3 + q4,"average": (q1 + q2 + q3 + q4) / 4})def format_currency(self, amount):"""格式化货币金额"""symbols = {"CNY": "¥", "USD": "$", "EUR": "€", "GBP": "£"}symbol = symbols.get(self.currency, self.currency)return f"{symbol}{amount:,.2f}"def generate_report(self):"""生成格式化报表"""print(f"\n{'='*80}")print(f"{self.company_name} - 年度财务报表".center(80))print(f"{'='*80}")# 表头headers = ["项目", "第一季度", "第二季度", "第三季度", "第四季度", "年度总计", "季度平均"]header_line = " | ".join(f"{header:^12}" for header in headers)print(f"| {header_line} |")print(f"|{'='*80}|")# 数据行grand_total = 0for record in self.data:category = f"{record['category']:<12}"q1 = f"{self.format_currency(record['q1']):>12}"q2 = f"{self.format_currency(record['q2']):>12}"q3 = f"{self.format_currency(record['q3']):>12}"q4 = f"{self.format_currency(record['q4']):>12}"total = f"{self.format_currency(record['total']):>12}"average = f"{self.format_currency(record['average']):>12}"data_line = " | ".join([category, q1, q2, q3, q4, total, average])print(f"| {data_line} |")grand_total += record['total']print(f"|{'='*80}|")# 总计行print(f"| {'年度总计':<12} | {'':>12} | {'':>12} | {'':>12} | {'':>12} | "f"{self.format_currency(grand_total):>12} | {'':>12} |")print(f"{'='*80}")# 使用示例
report = FinancialReport("某科技有限公司", "CNY")
report.add_record("营业收入", 1250000, 1380000, 1520000, 1680000)
report.add_record("营业成本", 750000, 820000, 890000, 950000)
report.add_record("毛利润", 500000, 560000, 630000, 730000)
report.add_record("净利润", 250000, 280000, 315000, 365000)report.generate_report()
10. 总结
本文全面介绍了Python字符串格式化的各种方法,从基础的f-string到传统的%操作符,涵盖了浮点数精度控制、宽度对齐、符号显示等各个方面。通过大量的表格和实际示例,展示了如何在实际项目中应用这些格式化技巧。
关键要点总结:
- f-string是现代Python的首选,语法简洁,性能优秀
- 精度控制使用
:.precisionf语法,支持动态精度 - 宽度和对齐控制可以创建美观的表格输出
- 了解四舍五入规则对于精确计算很重要
- 根据项目需求选择合适的格式化方法
掌握这些字符串格式化技巧,将大大提高你的Python编程效率,让你能够生成专业、美观的数据展示和报告。
# 快速参考卡片
def formatting_quick_reference():"""格式化快速参考"""examples = [("基本精度", "f'{3.1415926:.2f}'", "3.14"),("宽度对齐", "f'{12.3456:10.2f}'", " 12.35"),("符号显示", "f'{12.34:+.2f}'", "+12.34"),("千位分隔", "f'{1234567:,.2f}'", "1,234,567.00"),("科学计数", "f'{0.000123456:.2e}'", "1.23e-04"),("百分比", "f'{0.875:.2%}'", "87.50%"),]print("Python字符串格式化快速参考")print("=" * 60)for desc, code, result in examples:print(f"{desc:12} {code:30} → {result}")print("=" * 60)# 显示快速参考
formatting_quick_reference()
通过本指南的学习,你应该能够熟练运用Python的各种字符串格式化技巧,在实际开发中生成专业、美观的输出结果。
