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

2.3 格式化

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

      Name      Shares        Price
---------- ---------- -----------
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'
>>>

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

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

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

格式码

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

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

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

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

字典格式化

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

>>> s = {
'name': 'IBM',
'shares': 100,
'price': 91.1
}
>>> '{name:>10s} {shares:10d} {price:10.2f}'.format_map(s)
' IBM 100 91.10'
>>>

虽然 format_map()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-strings。

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 %n messages' % (b'Dave', 37)
b'Dave has 37 messages'
>>>

练习

练习 2.8:如何格式化数字

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

>>> 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-strings 使用的格式码的完整文档在 这里 可以找到。有时,也使用字符串操作符 % 执行格式化。

>>> 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。在本练习中,需要修改这个程序来生成如下表格:

      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

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

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

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

>>> portfolio = read_portfolio('Data/portfolio.csv')
>>> prices = read_prices('Data/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 循环,但是请更改打印语句以格式化元祖。

>>> 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-strings 扩展值。例如:

>>> 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'

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

'---------- ---------- ---------- -----------'

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

      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:格式化挑战

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

      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.2 容器) | 下一节 (2.4 序列)

注:完整翻译见 https://github.com/codists/practical-python-zh

翻译:《实用的Python编程》02_03_Formatting的更多相关文章

  1. 翻译:《实用的Python编程》InstructorNotes

    实用的 Python 编程--讲师说明 作者:戴维·比兹利(David Beazley) 概述 对于如何使用我的课程"实用的 Python 编程"进行教学的问题,本文档提供一些通用 ...

  2. 翻译:《实用的Python编程》README

    欢迎光临 大约 25 年前,当我第一次学习 Python 时,发现 Python 竟然可以被高效地应用到各种混乱的工作项目上,我立即被震惊了.15 年前,我自己也将这种乐趣教授给别人.教学的结果就是本 ...

  3. 翻译:《实用的Python编程》05_02_Classes_encapsulation

    目录 | 上一节 (5.1 再谈字典) | 下一节 (6 生成器) 5.2 类和封装 创建类时,通常会尝试将类的内部细节进行封装.本节介绍 Python 编程中有关封装的习惯用法(包括私有变量和私有属 ...

  4. 翻译:《实用的Python编程》04_02_Inheritance

    目录 | 上一节 (4.1 类) | 下一节 (4.3 特殊方法) 4.2 继承 继承(inheritance)是编写可扩展程序程序的常用手段.本节对继承的思想(idea)进行探讨. 简介 继承用于特 ...

  5. 翻译:《实用的Python编程》01_02_Hello_world

    目录 | 上一节 (1.1 Python) | 下一节 (1.3 数字) 1.2 第一个程序 本节讨论有关如何创建一个程序.运行解释器和调试的基础知识. 运行 Python Python 程序始终在解 ...

  6. 翻译:《实用的Python编程》03_03_Error_checking

    目录 | 上一节 (3.2 深入函数) | 下一节 (3.4 模块) 3.3 错误检查 虽然前面已经介绍了异常,但本节补充一些有关错误检查和异常处理的其它细节. 程序是如何运行失败的 Python 不 ...

  7. 翻译:《实用的Python编程》03_04_Modules

    目录 | 上一节 (3.3 错误检查) | 下一节 (3.5 主模块) 3.4 模块 本节介绍模块的概念以及如何使用跨多个文件的函数. 模块和导入 任何一个 Python 源文件都是一个模块. # f ...

  8. 翻译:《实用的Python编程》03_05_Main_module

    目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论) 3.5 主模块 本节介绍主程序(主模块)的概念 主函数 在许多编程语言中,存在一个主函数或者主方法的概念. // c / c++ ...

  9. 翻译:《实用的Python编程》04_01_Class

    目录 | 上一节 (3.6 设计讨论) | 下一节 (4.2 继承) 4.1 类 本节介绍 class 语句以及创建新对象的方式. 面向对象编程(OOP) 面向对象编程是一种将代码组织成对象集合的编程 ...

随机推荐

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. Codeforces Global Round 11 D. Unshuffling a Deck(构造/相邻逆序对)

    题目链接:https://codeforces.com/contest/1427/problem/D 题意 给出一个大小为 \(n\) 的排列,每次操作可以将 \(n\) 个数分为 \(1 \sim ...

  3. Educational Codeforces Round 30

    Educational Codeforces Round 30  A. Chores 把最大的换掉 view code #pragma GCC optimize("O3") #pr ...

  4. windows10与linux进行ftp遇到550 Failed to change directory及553 Could not creat file

    第一个原因: 没有权限,可以使用带有l参数的ls命令来看文件或者目录的权限 ls -l 解决:给本地用户添加一个可写权限 chmod +w /home/student ##给对应的本地用户添加一个可写 ...

  5. Codeforces301D. Yaroslav and Divisors

    题意:2e5的全排列 每次询问一个区间有多少对数 满足一个数是另一个数的倍数 题解:考虑离线来做 看到有个说法说 在处理有两种约束的问题时 一般用数据结构边插入边询问的方式 这个题正是如此 我们用su ...

  6. Codeforces Round #653 (Div. 3)

    比赛链接:https://codeforces.com/contest/1374 A. Required Remainder 题意 给出 $x, y, n$,找到最大的整数 $0 \le k \le ...

  7. 【洛谷 p3376】模板-网络最大流(图论)

    题目:给出一个网络图,以及其源点和汇点,求出其网络最大流. 解法:网络流Dinic算法. 1 #include<cstdio> 2 #include<cstdlib> 3 #i ...

  8. P1714 切蛋糕 dp+单调队列

    题意: 题目描述 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精. 某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到 ...

  9. Git管理远程仓库

    一:使用远程仓库的目的 作用:备份,实现代码共享集中化管理: 二:将git本地仓库同步到远程仓库流程图 三:Git克隆操作 目的: 将远程仓库(github远程仓库项目代码)克隆到本地 如何克隆 1. ...

  10. K8S(10)配置中心实战-configmap资源

    k8s配置中心实战-configmap资源 目录 k8s配置中心实战-configmap资源 0 configmap前置说明 0.1.1 configmap和secret 0.1.2 怎么使用conf ...