前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >盘一盘 Python 系列特别篇 - 格式化 String

盘一盘 Python 系列特别篇 - 格式化 String

作者头像
用户5753894
发布2020-03-13 13:14:53
7040
发布2020-03-13 13:14:53
举报
文章被收录于专栏:王的机器

引言

格式化字符串(string formatting)是以指定输出参数格式相对位置来“美化”字符串。输出参数格式包括数字的小数点位数、字符串大小写等,相对位置标注出被格式化的词是在句中的位置。比如

代码语言:javascript
复制
 'It costs %.2f.' %(123.456)

其中 %.2f 是 123.456 的输出参数格式,.2f 代表保留小数点两位,而 %.2f 所在的位置在 costs 后面,意思说将 123.456 变成 123.46 后插在 costs 后面。

代码语言:javascript
复制
print('It costs %.2f.' %(123.456))
代码语言:javascript
复制
It costs 123.46.

格式化字符串有四种方法:

  1. 用 % 字符 (上面用的)
  2. 用 $ 字符
  3. 用 format() 函数
  4. 用 f-string

本帖思路极其简单

  • 第一章先比较上述四种格式化方法,让它们完成同样的任务,谁好谁坏一目了然。
  • 第二章选出两个胜者,format() 函数和 f-string,对它们再做一个全方位的对比(),选出一个最后胜者 f-string。
  • 第三章总结,用 f-string!用 f-string!用 f-string!

1、四种格式化方法

整帖中都以下面这句话举例子,即“在 2020 年 3 月 4 日,阿里巴巴的市值为 553789 百万美元”。

代码语言:javascript
复制
s = 'On 04 Mar 2020, the market cap of Alibaba is 553789 mio USD.'
s
代码语言:javascript
复制
'On 04 Mar 2020, the market cap of Alibaba is 553789 mio USD.'

首先定义市值(Mcap)和货币单位(curr)两个变量。

代码语言:javascript
复制
Mcap = 553789
curr = 'USD'

下面开始比较四种格式化的方法,用心去感受哪种最好。

用 % 字符格式化

代码语言:javascript
复制
'The market cap of Alibaba is %d mio %s.' %(Mcap, curr)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

该方法的核心范式是:

首先写句子;再用 % 加小括号,里面列出要被格式化的变量名;最后在句子一一对应变量名的地方写出 %x(d 代表数字,s 代表字符串,等等)。

照着上面具体例子品一遍,该方法不是很方便对吧。

用 $ 字符格式化

代码语言:javascript
复制
from string import Template
info = dict(Mcap=Mcap, curr=curr)
Template('The market cap of Alibaba is $Mcap mio $curr.')
        .substitute(info)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

该方法的核心范式是:

在此方法下,我们需要将变量名和变量值作为键和值,创建一个字典。

首先要调用 Template 库函数并将句子传给它;再把字典传入 substitute() 函数;最后在句子一一对应变量名的地方写出 $k(k 代表字典中的键)。

照着上面具体例子品一遍,该方法也不是很方便对吧,而且还要引用额外的库函数。

用 format 函数格式化

代码语言:javascript
复制
'The market cap of Alibaba is {} mio {}.'.format(Mcap, curr)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

该方法的核心范式是:

首先写句子;再用 format() 函数,里面列出要被格式化的变量名;最后在句子一一对应变量名的地方只用写出 {}。

照着上面具体例子品一遍,该方法还可以对吧,但还是有些冗长。

用 f-string 方法格式化

代码语言:javascript
复制
f'The market cap of Alibaba is {Mcap} mio {curr}.'
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

该方法的核心范式是:

首先写出句子,以 f' 'F' ' 的形式;然后在句子只用写出 {v},其中 v 是要被格式的变量。

照着上面具体例子品一遍,f-string 不能更方便是吧。很显然它比其他三个用起来更简单更自然,更强的是它还是最快的。

当决定用哪种格式化时,通常我们评估它是否简单直观而且符合自己的习惯,比如

  • 那些有 C 语言背景的使用者就偏向用 “%” 字符
  • 那些偏好标准化的使用者就偏向用 "$" 字符
  • 那些偏好个性化的使用者就偏向用 format 函数

而我就喜欢 f-string 方法,下节就来比较 format 函数和 f-string 方法。我发现只要 format 函数能做到的,f-string 都能做到,而且代码写出来更漂亮,运行更快,那为何不用呢?

2、Format Vs f-string

本节是两强相争,format() 函数和 f-string,它们两个能做的事几乎一样,比如都能接收字典型数据、列表型数据、类数据;都能给数字型变量保留小数点,加分隔符;都能个性化日期型变量,等等。

字典型数据

创建字典。

代码语言:javascript
复制
info = dict(Mcap=Mcap, curr=curr)
info
代码语言:javascript
复制
{'Mcap': 553789, 'curr': 'USD'}

先看 format() 函数。

大括号用 0 和 1 对应着 format() 函数中第 1 个和第 2 个参数。

代码语言:javascript
复制
'The market cap of Alibaba is {0} mio {1}.'
.format(info['Mcap'], info['curr'])
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

这样写有些麻烦,format() 函数只传进字典 info,而大括号里的 0 就代表它,0[Mcap] 和 0[curr] 就是用键来获取值。

代码语言:javascript
复制
'The market cap of Alibaba is {0[Mcap]} mio {0[curr]}.'.format(info)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

我们来看看 f-string,怎么出错了???

代码语言:javascript
复制
f'The market cap of Alibaba is {info['Mcap']} mio {info['curr']}.'
代码语言:javascript
复制
File "<ipython-input-26-1b50e8c7dcf6>", line 1
    f'The market cap of Alibaba is {info['Mcap']} mio {info['curr']}.'
                                             ^
SyntaxError: invalid syntax

因为一个完整的字符串句子是有前后单引号包住的,注意 f 后面有个单引号,而 info['Mcap'] 的前单引号被 Python 误认为一连串字符串结束了


怎么办呢?把 f-string 里的单引号改用双引号就可以了。

代码语言:javascript
复制
f"The market cap of Alibaba is {info['Mcap']} mio {info['curr']}."
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

关键词

创建字典,其键可当成关键词(keyword)。

代码语言:javascript
复制
info = {'Mcap':Mcap, 'curr':curr}
info
代码语言:javascript
复制
{'Mcap': 553789, 'curr': 'USD'}

先看 format() 函数。

用 ** 将字典打散传入 format 就可以了。

代码语言:javascript
复制
'The market cap of Alibaba is {Mcap} mio {curr}.'
.format(**info)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

**info 和 format(info['Mcap'], info['curr']) 是一样的。

列表型数据

创建列表。

代码语言:javascript
复制
info = [Mcap, curr]
info
代码语言:javascript
复制
[553789, 'USD']

先看 format() 函数。

format() 函数只传进列表 info,而大括号里的 0 就代表它,0[0] 和 0[1] 就是用索引来获取值。

代码语言:javascript
复制
'The market cap of Alibaba is {0[0]} mio {0[1]}.'
.format(info)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

再看 f-string,也是用索引来获取列表 info 中的值,但是代码更简洁。

代码语言:javascript
复制
f"The market cap of Alibaba is {info[0]} mio {info[1]}."
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

类数据

创建类 Info 并初始化一个对象 info。

代码语言:javascript
复制
class Info():
    def __init__(self, Mcap, curr): 
           self.Mcap = Mcap        
           self.curr = curr
代码语言:javascript
复制
info = Info(Mcap, curr)
info
代码语言:javascript
复制
<__main__.Info at 0x21113395048>

先看 format() 函数。

format() 函数只传进对象 info,而大括号里的 0 就代表它,0.Mcap 和 0.curr 就是用 info.method 的方式来获取值。

代码语言:javascript
复制
'The market cap of Alibaba is {0.Mcap} mio {0.curr}.'
.format(info)
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

再看 f-string,也是用 info.method 的方式来获取列表 info 中的值,但是代码更简洁。

代码语言:javascript
复制
f"The market cap of Alibaba is 
{info.Mcap} mio {info.curr}."
代码语言:javascript
复制
'The market cap of Alibaba is 553789 mio USD.'

每三位数加逗号 ,

还是用字典作为输入来举例。

代码语言:javascript
复制
info = dict(Mcap=Mcap, curr=curr)
info
代码语言:javascript
复制
{'Mcap': 553789, 'curr': 'USD'}

一般在打印钱的数额时候,每三位需要一个逗号隔开而便于阅读。

先看 format() 函数。

用 {0:,} 格式可以做到,重点是冒号和逗号。0 代表是 info[Mcap],即市值,是 553789。冒号后面跟着具体的格式,而逗号就是这个具体的格式。

代码语言:javascript
复制
'The market cap of Alibaba is {0:,} mio {1}.'
.format(info['Mcap'], info['curr'])
代码语言:javascript
复制
'The market cap of Alibaba is 553,789 mio USD.'

用 f-string 添加逗号的用法一样,只不过代码简洁些。

代码语言:javascript
复制
f"The market cap of Alibaba is 
{info['Mcap']:,} mio {info['curr']}."
代码语言:javascript
复制
'The market cap of Alibaba is 553,789 mio USD.'

换算单位

现在加入我们想把百万(mio)单位换算成十亿(bio),需要在市值 553789 上除以 1000。

首先在字典中多添加一个键值对,unit:'bio'。

代码语言:javascript
复制
info = dict(Mcap=Mcap, curr=curr, unit='bio')
info
代码语言:javascript
复制
{'Mcap': 553789, 'curr': 'USD', 'unit': 'bio'}

接下来看 format() 函数和 f-string 的格式化用法,后者明显简洁。

代码语言:javascript
复制
'The market cap of Alibaba is {0:,} {1} {2}.'
.format(info['Mcap']/1000, info['unit'], info['curr'])
代码语言:javascript
复制
'The market cap of Alibaba is 553.789 bio USD.'
代码语言:javascript
复制
f"The market cap of Alibaba is 
{info['Mcap']/1000:,} {info['unit']} {info['curr']}."
代码语言:javascript
复制
'The market cap of Alibaba is 553.789 bio USD.'

保留小数点位数

现在假如我们觉得小数点 3 位太多了,不要任何小数点。

先看 format() 函数。

用 {0:,.0f} 格式可以做到,冒号和逗号上面上面解释过。.0f 代表小数点后面保留 0 位。

代码语言:javascript
复制
'The market cap of Alibaba is {0:,.0f} {1} {2}.'
.format(info['Mcap']/1000, info['unit'], info['curr'])
代码语言:javascript
复制
'The market cap of Alibaba is 554 bio USD.'

用 f-string 的用法一样,只不过代码简洁些。

代码语言:javascript
复制
f"The market cap of Alibaba is 
{info['Mcap']/1000:,.0f} {info['unit']} {info['curr']}."
代码语言:javascript
复制
'The market cap of Alibaba is 554 bio USD.'

加入日期

首先引入 datetime,创建日期。

代码语言:javascript
复制
from datetime import 
datetimedate = datetime(2020, 3, 4)

在字典中增加一个键值对,date: datetime(2020, 3, 4)。

代码语言:javascript
复制
info = dict(date=date, Mcap=Mcap, curr=curr, unit='bio')
info
代码语言:javascript
复制
{'date': datetime.datetime(2020, 3, 4, 0, 0),
 'Mcap': 553789,
 'curr': 'USD',
 'unit': 'bio'}

接下来比较 format() 函数和 f-string,后者明显简洁。

代码语言:javascript
复制
'On {3}, the market cap of Alibaba is {0:,.0f} {1} {2}.'
.format(info['Mcap']/1000, info['unit'], info['curr'], info['date'])
代码语言:javascript
复制
'On 2020-03-04 00:00:00, the market cap of Alibaba is 554 bio USD.'
代码语言:javascript
复制
f"On {info['date']}, the market cap of Alibaba is 
{info['Mcap']/1000:,.0f} {info['unit']} {info['curr']}."
代码语言:javascript
复制
'On 2020-03-04 00:00:00, the market cap of Alibaba is 554 bio USD.'

但日期格式太难看了,调整日期格式可参考 https://strftime.org/。

  • %Y - 年的全称 (如 2020)
  • %b - 月份的简称 (如 Mar)
  • %d - 天数 (如果是个位数用零填充,如 03)
  • %a - 日期的简称 (Wed)

结果如下:

代码语言:javascript
复制
'On {3:%b %d, %Y (%a)}, the market cap of Alibaba is {0:,.0f} {1} {2}.'
.format(info['Mcap']/1000, info['unit'], info['curr'], info['date'])
代码语言:javascript
复制
'On Mar 04, 2020 (Wed), the market cap of Alibaba is 554 bio USD.'
代码语言:javascript
复制
f"On {info['date']:%b %d, %Y (%a)}, the market cap of Alibaba is 
{info['Mcap']/1000:,.0f} {info['unit']} {info['curr']}."
代码语言:javascript
复制
'On Mar 04, 2020 (Wed), the market cap of Alibaba is 554 bio USD.'

3、总结

困死了,不想总结了。以后想格式化字符串用 f-string 就完事了。如果真嗷嗷想用别的那就看张图吧。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 王的机器 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 1、四种格式化方法
    • 用 % 字符格式化
      • 用 $ 字符格式化
        • 用 format 函数格式化
          • 用 f-string 方法格式化
          • 2、Format Vs f-string
            • 字典型数据
              • 关键词
                • 列表型数据
                  • 类数据
                    • 每三位数加逗号 ,
                      • 换算单位
                        • 保留小数点位数
                          • 加入日期
                          • 3、总结
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档