9.2 KiB
doc_type, full_text
| doc_type | full_text |
|---|---|
| short | sources/03_Formatting.md |
03_Formatting 总结
本文讲解 Python 中用于生成结构化文本输出的字符串格式化技术,重点服务于数据处理场景中的表格输出,例如股票投资组合报表。内容承接前文的容器与数据读取练习,并为后续更复杂的数据展示打基础。相关主题可延伸为 Python字符串格式化、concepts/表格化输出、股票投资组合报表。
核心主题
在处理数据时,经常需要把原始数据整理成易读的结构化输出,例如对齐的表格:
Name Shares Price
---------- ---------- -----------
AA 100 32.20
IBM 50 91.10
本文介绍了多种 Python 字符串格式化方式:
- f-string,即格式化字符串字面量
str.format_map(),从字典中取值格式化str.format(),通过位置参数或关键字参数格式化- C 风格
%格式化
其中,作者明显偏好 Python 3.6+ 的 f-string,因为它简洁、直观,适合常规字符串输出。
f-string 格式化
f-string 使用 {expression:format} 形式,将表达式的值插入字符串,并按指定格式显示。
示例:
name = 'IBM'
shares = 100
price = 91.1
f'{name:>10s} {shares:>10d} {price:>10.2f}'
结果:
' IBM 100 91.10'
这里的格式说明含义是:
{name:>10s}:字符串右对齐,占 10 个字符宽度{shares:>10d}:十进制整数右对齐,占 10 个字符宽度{price:>10.2f}:浮点数右对齐,占 10 个字符宽度,保留 2 位小数
f-string 通常和 print() 搭配使用,但它本质上只是生成字符串,并不依赖打印。
常用格式代码
格式代码位于 {} 中冒号 : 后面,风格类似 C 语言 printf()。
常见类型代码包括:
d 十进制整数
b 二进制整数
x 十六进制整数
f 浮点数,形如 [-]m.dddddd
e 科学计数法浮点数,形如 [-]m.dddddde+-xx
g 浮点数,根据情况选择普通或科学计数法
s 字符串
c 字符,由整数转换而来
常见修饰符包括:
:>10d 整数右对齐,占 10 个字符宽度
:<10d 整数左对齐,占 10 个字符宽度
:^10d 整数居中,占 10 个字符宽度
:0.2f 浮点数保留 2 位小数
这些规则是 Python字符串格式化 的基础,也直接支撑 concepts/表格化输出。
字典格式化:format_map()
format_map() 可将一个字典中的值应用到格式化字符串中。
示例:
s = {
'name': 'IBM',
'shares': 100,
'price': 91.1
}
'{name:>10s} {shares:10d} {price:10.2f}'.format_map(s)
输出:
' IBM 100 91.10'
它使用与 f-string 相同的格式代码,但值来自传入字典。这种方式适合数据本身已经以字典形式组织的场景,和前文容器相关内容可关联到 Python容器。
format() 方法
format() 方法可以通过关键字参数或位置参数传入值。
关键字参数示例:
'{name:>10s} {shares:10d} {price:10.2f}'.format(
name='IBM', shares=100, price=91.1
)
位置参数示例:
'{:>10s} {:10d} {:10.2f}'.format('IBM', 100, 91.1)
两者都会产生类似输出:
' IBM 100 91.10'
不过本文认为 format() 相对冗长,日常更推荐 f-string。
C 风格 % 格式化
Python 也支持 % 运算符进行字符串格式化。
示例:
'The value is %d' % 3
'%5d %-5d %10d' % (3, 4, 5)
'%0.2f' % (3.1415926,)
这种方式要求右侧是一个单独值或元组,格式代码同样源自 C 的 printf()。
特别注意:字节串 bytes 只支持这种 % 格式化方式。
b'%s has %d messages' % (b'Dave', 37)
b'%b has %d messages' % (b'Dave', 37)
这说明 % 格式化虽然较旧,但在处理 bytes 时仍然重要。
练习 2.8:数字格式化
本练习强调打印数字时如何控制小数位数、字段宽度、对齐方式、填充字符和千位分隔符。
示例:
value = 42863.1
print(f'{value:0.4f}')
print(f'{value:>16.2f}')
print(f'{value:<16.2f}')
print(f'{value:*>16,.2f}')
输出效果包括:
42863.1000
42863.10
42863.10
*******42,863.10
关键点:
.4f表示保留 4 位小数>16.2f表示右对齐,占 16 位,保留 2 位小数<16.2f表示左对齐*>16,.2f表示用*填充,右对齐,带千位分隔符,保留 2 位小数
练习也展示了 % 格式化的等价写法:
print('%0.4f' % value)
print('%16.2f' % value)
重要结论:格式化结果可以保存为变量,而不一定立即打印。
f = '%0.4f' % value
练习 2.9:收集报表数据
本练习要求扩展之前的 report.py,根据股票投资组合和价格字典生成报表数据。
目标是实现函数:
def make_report(portfolio, prices):
...
输入:
portfolio:股票持仓列表prices:当前价格字典
输出:
- 一个由元组组成的列表
- 每个元组表示报表的一行
- 元组字段为:股票名、股数、当前价格、价格变化
示例结果:
('AA', 100, 9.22, -22.980000000000004)
('IBM', 50, 106.28, 15.180000000000007)
('CAT', 150, 35.46, -47.98)
这一步强调先收集结构化数据,再处理输出格式。它把数据计算和数据显示分开,是 数据处理流程 中的重要设计思想。
练习 2.10:打印格式化表格
在获得 make_report() 的结果后,本练习要求将元组格式化输出为整齐表格。
使用 % 格式化:
for r in report:
print('%10s %10d %10.2f %10.2f' % r)
或者使用 f-string,并先解包元组:
for name, shares, price, change in report:
print(f'{name:>10s} {shares:>10d} {price:>10.2f} {change:>10.2f}')
输出示例:
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
这里体现了两个关键技能:
- 元组解包
- 将不同类型的数据按列宽对齐输出
相关主题包括 元组解包 和 concepts/表格化输出。
练习 2.11:添加表头和分隔线
本练习要求给报表添加表头:
headers = ('Name', 'Shares', 'Price', 'Change')
目标表头字符串:
' Name Shares Price Change'
还要生成分隔线:
'---------- ---------- ---------- -----------'
最终输出应为:
Name Shares Price Change
---------- ---------- ---------- ----------
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
这一练习将前面的字段宽度、右对齐和循环输出结合起来,用于构造完整的命令行表格报表。
练习 2.12:格式化挑战:货币符号
最后的挑战要求修改价格列,使其包含美元符号 $。
目标效果:
Name Shares Price Change
---------- ---------- ---------- ----------
AA 100 $9.22 -22.98
IBM 50 $106.28 15.18
CAT 150 $35.46 -47.98
这要求在数值格式化之外加入字符串拼接或嵌套格式化思路,例如先把价格格式化成带 $ 的字符串,再作为字符串右对齐输出。
该练习强化了一个重要认识:格式化不仅是控制数字精度,也包括构造适合人类阅读的展示形式。
关键知识点
- f-string 是 Python 3.6+ 中推荐的字符串格式化方式之一。
{expression:format}可同时完成求值与格式控制。- 常用控制项包括字段宽度、对齐方向、小数位数、填充字符和千位分隔符。
format_map()适合使用字典数据进行格式化。format()支持位置参数和关键字参数,但写法较冗长。%格式化是旧式写法,但仍用于bytes格式化。- 表格输出通常需要:表头、分隔线、数据行、字段宽度和对齐规则。
- 数据处理程序应先生成结构化数据,再统一格式化输出。
与其他主题的关系
本文可与以下概念页面建立联系:
- Python字符串格式化:总结 f-string、
format()、format_map()和%格式化。 - concepts/表格化输出:跨文档整理如何在命令行生成整齐表格。
- 股票投资组合报表:围绕
portfolio.csv、prices.csv、report.py的系列练习。 - 数据处理流程:从读取数据、组织数据、计算结果到格式化输出。
- Python容器:本章练习依赖列表、字典和元组等容器组织数据。
- 元组解包:在格式化报表行时将一行数据拆成多个变量。