python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python字符串格式化

Python中多种字符串格式化的完整方法指南

作者:Kratzdisteln

在日常编程中,我们经常需要将各种数据类型转换为美观、易读的字符串形式,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左对齐,宽度10f"|{12.3456:<10.2f}|"|12.35 |
:>10.2f右对齐,宽度10f"|{12.3456:>10.2f}|"| 12.35|
:^10.2f居中对齐,宽度10f"|{12.3456:^10.2f}|"| 12.35 |
:*^10.2f居中对齐,填充*f"{12.3456:*^10.2f}"***12.35***
:0>10.2f右对齐,填充0f"{12.3456:0>10.2f}"0000012.35

2.5 符号显示控制

positive = 12.34
negative = -12.34

print(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.14153.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.14153
%s字符串"%s" % 3.14153.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.2341.23直接舍去(4小于5)
1.2351.24五入(5等于5,前一位是奇数3)
1.2361.24五入(6大于5)
1.2251.22银行家舍入(5等于5,前一位是偶数2)
1.2451.24银行家舍入(5等于5,前一位是偶数4)
2.6752.68五入(5等于5,前一位是奇数7)
2.6652.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"]) * 100
        
        print(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 timeit

def performance_comparison():
    """各种格式化方法性能比较"""
    
    # 测试数据
    name = "测试用户"
    value = 1234.56789
    count = 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 最佳实践总结

9. 完整实战示例

class FinancialReport:
    """财务报表生成器"""
    
    def __init__(self, company_name, currency="CNY"):
        self.company_name = company_name
        self.currency = currency
        self.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 = 0
        for 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到传统的%操作符,涵盖了浮点数精度控制、宽度对齐、符号显示等各个方面。通过大量的表格和实际示例,展示了如何在实际项目中应用这些格式化技巧。

关键要点总结:

掌握这些字符串格式化技巧,将大大提高你的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的各种字符串格式化技巧,在实际开发中生成专业、美观的输出结果。

到此这篇关于Python中多种字符串格式化的完整方法指南的文章就介绍到这了,更多相关Python字符串格式化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文