简介
本节稍有离题,但当你处理数据时,常常希望生成结构化输出(表格等)。例如:
名称 股票数量 价格
---------- ---------- -----------
AA 100 32.20
IBM 50 91.10
CAT 150 83.44
MSFT 200 51.23
GE 95 40.37
MSFT 50 65.10
IBM 100 70.44
字符串格式化
在 Python 3.6 及以上版本中,一种格式化字符串的方法是使用 f-strings。
>>> name = 'IBM'
>>> shares = 100
>>> price = 91.1
>>> f'{name:>10s} {shares:>10d} {price:>10.2f}'
' IBM 100 91.10'
>>>
{表达式:格式} 这部分会被替换。
它通常与 print 一起使用。
print(f'{name:>10s} {shares:>10d} {price:>10.2f}')
格式代码
格式代码(在 {} 内部的 : 之后)类似于 C 语言中的 printf()。常见的代码包括:
d 十进制整数
b 二进制整数
x 十六进制整数
f 浮点数格式为 [-]m.dddddd
e 浮点数格式为 [-]m.dddddde+-xx
g 浮点数,但根据情况选择使用科学计数法
s 字符串
c 字符(由整数转换而来)
常见的修饰符用于调整字段宽度和小数精度。以下是部分列表:
:>10d 整数在10个字符宽度的字段中右对齐
:<10d 整数在10个字符宽度的字段中左对齐
:^10d 整数在10个字符宽度的字段中居中
:0.2f 具有2位小数精度的浮点数
字典格式化
你可以使用 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-strings 相同的代码,但从提供的字典中获取值。
format() 方法
有一个 format() 方法,它可以对参数或关键字参数应用格式化。
>>> '{name:>10s} {shares:10d} {price:10.2f}'.format(name='IBM', shares=100, price=91.1)
' IBM 100 91.10'
>>> '{:>10s} {:10d} {:10.2f}'.format('IBM', 100, 91.1)
' IBM 100 91.10'
>>>
坦率地说,format() 有点冗长。我更喜欢 f 字符串。
C 风格格式化
你也可以使用格式化运算符 %。
>>> 'The value is %d' % 3
'The value is 3'
>>> '%5d %-5d %10d' % (3,4,5)
' 3 4 5'
>>> '%0.2f' % (3.1415926,)
'3.14'
这要求右边是单个项或一个元组。格式代码也是仿照 C 语言的 printf()。
注意:这是字节串上唯一可用的格式化方式。
>>> b'%s has %d messages' % (b'Dave', 37)
b'Dave has 37 messages'
>>> b'%b has %d messages' % (b'Dave', 37) ## 可以使用 %b 代替 %s
b'Dave has 37 messages'
>>>
练习 2.8:如何格式化数字
打印数字时常见的一个问题是指定小数位数。解决这个问题的一种方法是使用 f 字符串。试试这些示例:
>>> value = 42863.1
>>> print(value)
42863.1
>>> print(f'{value:0.4f}')
42863.1000
>>> print(f'{value:>16.2f}')
42863.10
>>> print(f'{value:<16.2f}')
42863.10
>>> print(f'{value:*>16,.2f}')
*******42,863.10
>>>
有关 f 字符串中使用的格式化代码的完整文档可在此处找到。格式化有时也使用字符串的%运算符来执行。
>>> print('%0.4f' % value)
42863.1000
>>> print('%16.2f' % value)
42863.10
>>>
有关与%一起使用的各种代码的文档可在此处找到。
虽然它通常与print一起使用,但字符串格式化并不局限于打印。如果你想保存格式化后的字符串,只需将其赋给一个变量。
>>> f = '%0.4f' % value
>>> f
'42863.1000'
>>>
练习 2.9:收集数据
在练习 2.7 中,你编写了一个名为report.py的程序,用于计算股票投资组合的收益/损失。在本练习中,你将开始对其进行修改,以生成如下表格:
| 名称 | 股数 | 价格 | 变化 |
|---|---|---|---|
| AA | 100 | 9.22 | -22.98 |
| IBM | 50 | 106.28 | 15.18 |
| CAT | 150 | 35.46 | -47.98 |
| MSFT | 200 | 20.89 | -30.34 |
| GE | 95 | 13.48 | -26.89 |
| MSFT | 50 | 20.89 | -44.21 |
| IBM | 100 | 106.28 | 35.84 |
在本报告中,“价格”是股票的当前股价,“变化”是股价相对于初始购买价格的变化。
为了生成上述报告,你首先需要收集表格中显示的所有数据。编写一个函数make_report(),该函数以股票列表和价格字典作为输入,并返回一个包含上述表格各行的元组列表。
将此函数添加到你的report.py文件中。如果进行交互式尝试,它应该如下工作:
>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> prices = read_prices('/home/labex/project/prices.csv')
>>> report = make_report(portfolio, prices)
>>> for r in report:
print(r)
('AA', 100, 9.22, -22.980000000000004)
('IBM', 50, 106.28, 15.180000000000007)
('CAT', 150, 35.46, -47.98)
('MSFT', 200, 20.89, -30.339999999999996)
('GE', 95, 13.48, -26.889999999999997)
...
>>>
练习 2.10:打印格式化表格
重做练习 2.9 中的 for 循环,但将 print 语句修改为格式化元组。
>>> for r in report:
print('%10s %10d %10.2f %10.2f' % r)
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
...
>>>
你也可以展开这些值并使用 f 字符串。例如:
>>> 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
MSFT 200 20.89 -30.34
...
>>>
将上述语句添加到你的report.py程序中。让你的程序获取make_report()函数的输出,并打印出一个格式良好的表格,如下所示。
练习 2.11:添加一些表头
假设你有一个如下所示的表头名称元组:
headers = ('Name', 'Shares', 'Price', 'Change')
在你的程序中添加代码,该代码接受上述表头元组,并创建一个字符串,其中每个表头名称在一个 10 字符宽的字段中右对齐,并且每个字段之间用单个空格分隔。
' 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 |
| GE | 95 | 13.48 | -26.89 |
| MSFT | 50 | 20.89 | -44.21 |
| IBM | 100 | 106.28 | 35.84 |
练习 2.12:格式化挑战
你会如何修改你的代码,以便价格包含货币符号($),并且输出如下所示:
| 名称 | 股数 | 价格 | 变化 |
|---|---|---|---|
| AA | 100 | $9.22 | -22.98 |
| IBM | 50 | $106.28 | 15.18 |
| CAT | 150 | $35.46 | -47.98 |
| MSFT | 200 | $20.89 | -30.34 |
| GE | 95 | $13.48 | -26.89 |
| MSFT | 50 | $20.89 | -44.21 |
| IBM | 100 | $106.28 | 35.84 |
总结
恭喜你!你已经完成了格式化实验。你可以在 LabEx 中练习更多实验来提高你的技能。