目录 | 上一节 (2.2 容器) | 下一节 (2.4 序列)

2.3 格式化

虽然本节稍微有点离题,但是当处理数据时,通常想要生成结构化的输出(如表格)。示例:

  1. Name Shares Price
  2. ---------- ---------- -----------
  3. AA 100 32.20
  4. IBM 50 91.10
  5. CAT 150 83.44
  6. MSFT 200 51.23
  7. GE 95 40.37
  8. MSFT 50 65.10
  9. IBM 100 70.44

字符串格式化

在 Python 3.6+ 中,格式化字符串的一种方法是使用 f-strings

  1. >>> name = 'IBM'
  2. >>> shares = 100
  3. >>> price = 91.1
  4. >>> f'{name:>10s} {shares:>10d} {price:>10.2f}'
  5. ' IBM 100 91.10'
  6. >>>

{expression:format} 部分会被取代。

f-strings 通常和 print() 函数一起使用:

  1. print(f'{name:>10s} {shares:>10d} {price:>10.2f}')

格式码

格式码(在 {}: 之后)与 C 语言的 printf() 函数类似。常见格式码包括:

  1. d Decimal integer
  2. b Binary integer
  3. x Hexadecimal integer
  4. f Float as [-]m.dddddd
  5. e Float as [-]m.dddddde+-xx
  6. g Float, but selective use of E notation
  7. s String
  8. c Character (from integer)

常见的修饰符可调整字段宽度和数的精度。这是部分内容:

  1. :>10d Integer right aligned in 10-character field
  2. :<10d Integer left aligned in 10-character field
  3. :^10d Integer centered in 10-character field
  4. :0.2f Float with 2 digit precision

字典格式化

可以使用字符串的 format_map() 方法将字符串格式化应用于值的字典:

  1. >>> s = {
  2. 'name': 'IBM',
  3. 'shares': 100,
  4. 'price': 91.1
  5. }
  6. >>> '{name:>10s} {shares:10d} {price:10.2f}'.format_map(s)
  7. ' IBM 100 91.10'
  8. >>>

虽然 format_map()f-strings 使用相同的格式码,但是是从提供的字典中获取值。

format()方法

有一个 format() 方法可以将格式化应用于参数或者关键字参数:

  1. >>> '{name:>10s} {shares:10d} {price:10.2f}'.format(name='IBM', shares=100, price=91.1)
  2. ' IBM 100 91.10'
  3. >>> '{:10s} {:10d} {:10.2f}'.format('IBM', 100, 91.1)
  4. ' IBM 100 91.10'
  5. >>>

坦白说,format() 方法稍微有点冗长,我更倾向于使用 f-strings。

C 风格的格式化

也可以使用格式化操作符 %

  1. >>> 'The value is %d' % 3
  2. 'The value is 3'
  3. >>> '%5d %-5d %10d' % (3,4,5)
  4. ' 3 4 5'
  5. >>> '%0.2f' % (3.1415926,)
  6. '3.14'

这要求右边是一个单项或者元组,格式码也是模仿 C 语言 printf() 函数的。

注意:这是字节字符串上唯一可用的格式化方法。

  1. >>> b'%s has %n messages' % (b'Dave', 37)
  2. b'Dave has 37 messages'
  3. >>>

练习

练习 2.8:如何格式化数字

打印数字常见的一个问题就是指定数字的小数位数。其中的一种解决方法就是使用 f-strings。请尝试以下示例:

  1. >>> value = 42863.1
  2. >>> print(value)
  3. 42863.1
  4. >>> print(f'{value:0.4f}')
  5. 42863.1000
  6. >>> print(f'{value:>16.2f}')
  7. 42863.10
  8. >>> print(f'{value:<16.2f}')
  9. 42863.10
  10. >>> print(f'{value:*>16,.2f}')
  11. *******42,863.10
  12. >>>

有关 f-strings 使用的格式码的完整文档在 这里 可以找到。有时,也使用字符串操作符 % 执行格式化。

  1. >>> print('%0.4f' % value)
  2. 42863.1000
  3. >>> print('%16.2f' % value)
  4. 42863.10
  5. >>>

与操作符 % 使用的各种格式码有关的文档可以在 这里 找到。尽管它通常与 print() 函数一起使用,但是字符串格式化与打印无关。如果要保存格式化的字符串,把它赋值给变量即可。

  1. >>> f = '%0.4f' % value
  2. >>> f
  3. '42863.1000'
  4. >>>

练习 2.9:收集数据

在练习 2.7 中,编写了一个用于计算股票投资盈亏的程序 report.py。在本练习中,需要修改这个程序来生成如下表格:

  1. Name Shares Price Change
  2. ---------- ---------- ---------- ----------
  3. AA 100 9.22 -22.98
  4. IBM 50 106.28 15.18
  5. CAT 150 35.46 -47.98
  6. MSFT 200 20.89 -30.34
  7. GE 95 13.48 -26.89
  8. MSFT 50 20.89 -44.21
  9. IBM 100 106.28 35.84

在此表格中,”Price” 是当前股价,”Change” 是当前股价与原始购买股价的差。

为了生成上述表格,首先需要收集表中展示的所有数据。编写 make_report() 函数,以股票列表和价格字典作为输入,并返回一个包含上表中所有行的元组列表。

make_report() 函数添加到 report.py 文件中。如果交互式地执行该函数,则应该按以下步骤进行:

  1. >>> portfolio = read_portfolio('Data/portfolio.csv')
  2. >>> prices = read_prices('Data/prices.csv')
  3. >>> report = make_report(portfolio, prices)
  4. >>> for r in report:
  5. print(r)
  6. ('AA', 100, 9.22, -22.980000000000004)
  7. ('IBM', 50, 106.28, 15.180000000000007)
  8. ('CAT', 150, 35.46, -47.98)
  9. ('MSFT', 200, 20.89, -30.339999999999996)
  10. ('GE', 95, 13.48, -26.889999999999997)
  11. ...
  12. >>>

练习 2.10:打印格式化的表格

重做练习 2.9 中的 for 循环,但是请更改打印语句以格式化元组。

  1. >>> for r in report:
  2. print('%10s %10d %10.2f %10.2f' % r)
  3. AA 100 9.22 -22.98
  4. IBM 50 106.28 15.18
  5. CAT 150 35.46 -47.98
  6. MSFT 200 20.89 -30.34
  7. ...
  8. >>>

也可以使用 f-strings 扩展值。例如:

  1. >>> for name, shares, price, change in report:
  2. print(f'{name:>10s} {shares:>10d} {price:>10.2f} {change:>10.2f}')
  3. AA 100 9.22 -22.98
  4. IBM 50 106.28 15.18
  5. CAT 150 35.46 -47.98
  6. MSFT 200 20.89 -30.34
  7. ...
  8. >>>

把上面的语句添加到 report.py 程序中,让程序获取make_report() 的输出,并打印如打印如上图所示的格式化的表。

练习 2.11:添加标题

假定有一个像下面这样的标题名称元组:

  1. headers = ('Name', 'Shares', 'Price', 'Change')

把上面的标题元组代码添加到程序中,并且创建一个字符串,每个标题向右对齐并且宽度是10,每个字段使用单个空格分隔。

  1. ' Name Shares Price Change'

编写在标题和数据之间创建分隔字符串的代码。分隔字符串指每个字段名下的一串下划线(”-“)字符。例如:

  1. '---------- ---------- ---------- -----------'

当完成后,程序应生成本节顶部所示的表。

  1. Name Shares Price Change
  2. ---------- ---------- ---------- ----------
  3. AA 100 9.22 -22.98
  4. IBM 50 106.28 15.18
  5. CAT 150 35.46 -47.98
  6. MSFT 200 20.89 -30.34
  7. GE 95 13.48 -26.89
  8. MSFT 50 20.89 -44.21
  9. IBM 100 106.28 35.84

练习 2.12:格式化挑战

如何修改代码使得价格包括货币符号($),并且像下面这样输出:

  1. Name Shares Price Change
  2. ---------- ---------- ---------- ----------
  3. AA 100 $9.22 -22.98
  4. IBM 50 $106.28 15.18
  5. CAT 150 $35.46 -47.98
  6. MSFT 200 $20.89 -30.34
  7. GE 95 $13.48 -26.89
  8. MSFT 50 $20.89 -44.21
  9. IBM 100 $106.28 35.84

目录 | 上一节 (2.2 容器) | 下一节 (2.4 序列)