Python 全栈之路系列之字符串格式化
Python 目前提供的字符串格式化方式有 3 种:
%
方式.format
方式f-string
方式
前两种方式在Python2
和Python3
中都适用,%
方式是 Python 一直内置存在的,format
方式为后面才出来的,而f-string
是最新的格式化方式。
# 旧式%
格式化
- 参数格式
%[(name)][flags][width].[precision]typecode
- [(name)]
可选,用于选择指定的 key
- [flags]
可选,可供选择的值有:
值 | 说明 |
---|---|
+ | 右对齐;正数前加正好,负数前加负号 |
- | 左对齐;正数前无符号,负数前加负号 |
space | 右对齐;正数前加空格,负数前加负号 |
0 | 右对齐;正数前无符号,负数前加负号;用 0 填充空白处 |
- [width]
可选,占有宽度
- .[precision]
可选,小数点后保留的位数
- typecode
必选,参数如下:
值 | 说明 |
---|---|
s | 获取传入对象的__str__方法的返回值,并将其格式化到指定位置 |
r | 获取传入对象的__repr__方法的返回值,并将其格式化到指定位置 |
c | 整数:将数字转换成其 unicode 对应的值,10 进制范围为 0 <= i <= 1114111(py27 则只支持 0-255);字符:将字符添加到指定位置 |
o | 将整数转换成 八 进制表示,并将其格式化到指定位置 |
x | 将整数转换成十六进制表示,并将其格式化到指定位置 |
d | 将整数、浮点数转换成十进制表示,并将其格式化到指定位置 |
e | 将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写 e) |
E | 将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写 E) |
f | 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后 6 位) |
F | 同上 |
g | 自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过 6 位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是 e;) |
G | 自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过 6 位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是 E;) |
% | 当字符串中存在格式化标志时,需要用 %% 表示一个% |
# 格式化实例
- 常用字符串格式化方式
# %s 代表字符串
>>> string = "My name is: %s" % ("ansheng")
>>> string
'My name is: ansheng'
2
3
4
- 字符串中出现
%
号的次数要与%
之后所提供的数据项个数相同,如果需要插入多个数据,则需要将他们封装进一个元组。
# %s是姓名,%d是年龄,必须是一个整数,不然会报错
>>> string = "My name is: %s, I am %d years old" % ("anshen", 20)
>>> string
'My name is: anshen, I am 20 years old'
2
3
4
- 给参数起一个名字,后面传值的时候必须是一个字典
# %(name)s是姓名,%(age)d是年龄,必须是一个整数,传入的值是一个字典格式
>>> string = "My name is: %(name)s, I am %(age)d years old" % {"name":"anshen", "age":20}
>>> string
'My name is: anshen, I am 20 years old'
2
3
4
- 去浮点数后面的位数
# %.2f小数后面只取两位
>>> string = "percent %.2f" % 99.97623
>>> string
'percent 99.98'
2
3
4
- 给浮点数起一个名字(key)
>>> string = "percent %(pp).2f" % {"pp":99.97623}
>>> string
'percent 99.98'
2
3
- 两个
%
代表一个%
>>> string = "percent %(pp).2f%%" % {"pp":99.97623}
>>> string
'percent 99.98%'
2
3
# 使用{}和 format 的新格式化
[[fill]align][sign][#][0][width][,][.precision][type]
- [fill]
可选,空白处填充的字符
- align
可选,对齐方式(需配合 width 使用)
参数 | 说明 |
---|---|
< | 强制内容左对齐 |
> | 强制内容右对齐(默认) |
= | 强制内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字 |
^ | 强制内容居中 |
- [sign]
可选,有无符号数字
参数 | 说明 |
---|---|
+ | 正号加正,负号加负 |
- | 正号不变,负号加负 |
space | 正号空格,负号加负 |
- [#]
可选,对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
- [,]
可选,为数字添加分隔符,如:1,000,000
- [width]
可选,格式化位所占宽度
- [.precision]
可选,小数位保留精度
- [type]
可选,格式化类型
- 传入” 字符串类型 “的参数
参数 | 说明 |
---|---|
s | 格式化字符串类型数据 |
空白 | 未指定类型,则默认是 None,同 s |
- 传入“ 整数类型 ”的参数
参数 | 说明 |
---|---|
b | 将 10 进制整数自动转换成 2 进制表示然后格式化 |
c | 将 10 进制整数自动转换为其对应的 unicode 字符 |
d | 十进制整数 |
o | 将 10 进制整数自动转换成 8 进制表示然后格式化; |
x | 将 10 进制整数自动转换成 16 进制表示然后格式化(小写 x) |
X | 将 10 进制整数自动转换成 16 进制表示然后格式化(大写 X) |
- 传入“ 浮点型或小数类型 ”的参数
参数 | 说明 |
---|---|
e | 转换为科学计数法(小写 e)表示,然后格式化; |
E | 转换为科学计数法(大写 E)表示,然后格式化; |
f | 转换为浮点型(默认小数点后保留 6 位)表示,然后格式化; |
F | 转换为浮点型(默认小数点后保留 6 位)表示,然后格式化; |
g | 自动在 e 和 f 中切换 |
G | 自动在 E 和 F 中切换 |
% | 显示百分比(默认显示小数点后 6 位) |
# format 格式化实例
- 第一种基本 format 格式化方式
>>> string = "My name is: {}, I am {} years old, {} Engineer".format("ansheng",20,"Python")
>>> string
'My name is: ansheng, I am 20 years old, Python Engineer'
2
3
- 第二种基本 format 格式化方式
>>> string = "My name is: {}, I am {} years old, {} Engineer".format(*["ansheng",20,"Python"])
>>> string
'My name is: ansheng, I am 20 years old, Python Engineer'
2
3
- 给传入的参数加一个索引
>>> string = "My name is: {0}, I am {1} years old, {0} Engineer".format(*["ansheng",20,"Python"])
>>> string
'My name is: ansheng, I am 20 years old, ansheng Engineer'
2
3
- 给参数起一个名字(key)
>>> string = "My name is: {name}, I am {age} years old, {job} Engineer".format(name="ansheng",age=20,job="Python")
>>> string
'My name is: ansheng, I am 20 years old, Python Engineer'
2
3
- 字典的方式
>>> string = "My name is: {name}, I am {age} years old, {job} Engineer".format(**{"name":"ansheng","age":20,"job":"Python"})
>>> string
'My name is: ansheng, I am 20 years old, Python Engineer'
2
3
- 索引内的索引
>>> string = "My name is: {0[0]}, I am {0[1]} years old, {0[2]} Engineer".format(["Ansheng",20,"Python"],["An",11,"IT"])
>>> string
'My name is: Ansheng, I am 20 years old, Python Engineer'
2
3
- 制定参数类型
>>> string = "My name is: {:s}, I am {:d} years old, {:f} wage".format("Ansheng",20,66666.55)
>>> string
'My name is: Ansheng, I am 20 years old, 66666.550000 wage'
2
3
- 制定名称(key)的值类型
>>> string = "My name is: {name:s}, I am {age:d} years old".format(name="Ansheng",age=20)
>>> string
'My name is: Ansheng, I am 20 years old'
2
3
- 异类实例
>>> string = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
>>> string
'numbers: 1111,17,15,f,F, 1587.623000%'
2
3
- 索引
>>> string = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
>>> string
'numbers: 1111,17,15,f,F, 1500.000000%'
2
3
# f-sting
格式化
原文:Python 格式化字符串 f-string 概览_sunxb10 的博客-CSDN 博客 (opens new window)
# 简介
f-string,亦称为格式化字符串常量(formatted string literals),是 Python3.6 新引入的一种字符串格式化方法,该方法源于PEP 498 – Literal String Interpolation (opens new window),主要目的是使格式化字符串的操作更加简便。f-string 在形式上是以 f
或 F
修饰符引领的字符串(f'xxx'
或 F'xxx'
),以大括号 {}
标明被替换的字段;f-string 在本质上并不是字符串常量,而是一个在运行时运算求值的表达式:
While other string literals always have a constant value, formatted strings are really expressions evaluated at run time.
(与具有恒定值的其它字符串常量不同,格式化字符串实际上是运行时运算求值的表达式。)
—— Python Documentation (opens new window)
f-string 在功能方面不逊于传统的%-formatting 语句 (opens new window)和str.format()
函数 (opens new window),同时性能 (opens new window)又优于二者,且使用起来也更加简洁明了,因此对于 Python3.6 及以后的版本,推荐使用 f-string 进行字符串格式化。
# 用法
此部分内容主要参考以下资料:
- Python Documentation – Formatted String Literals (opens new window)
- Python Documentation – Format String Syntax (opens new window)
- PEP 498 – Literal String Interpolation (opens new window)
- Python 3’s f-Strings: An Improved String Formatting Syntax (Guide) (opens new window)
- Python f-string tutorial - formatting strings in Python with f-string (opens new window)
- python3 f-string 格式化字符串的高级用法 (opens new window)
- Python 3: An Intro to f-strings (opens new window)
# 简单使用
f-string 用大括号 {}
表示被替换字段,其中直接填入替换内容:
>>> name = 'Eric'
>>> f'Hello, my name is {name}'
'Hello, my name is Eric'
>>> number = 7
>>> f'My lucky number is {number}'
'My lucky number is 7'
>>> price = 19.99
>>> f'The price of this book is {price}'
'The price of this book is 19.99'
2
3
4
5
6
7
8
9
10
11
# 表达式求值与函数调用
f-string 的大括号 {}
可以填入表达式或调用函数,Python 会求出其结果并填入返回的字符串内:
>>> f'A total number of {24 * 8 + 4}'
'A total number of 196'
>>> f'Complex number {(2 + 2j) / (2 - 3j)}'
'Complex number (-0.15384615384615388+0.7692307692307692j)'
>>> name = 'ERIC'
>>> f'My name is {name.lower()}'
'My name is eric'
>>> import math
>>> f'The answer is {math.log(math.pi)}'
'The answer is 1.1447298858494002'
2
3
4
5
6
7
8
9
10
11
12
13
# 引号、大括号与反斜杠
f-string 大括号内所用的引号不能和大括号外的引号定界符冲突,可根据情况灵活切换 '
和 "
:
>>> f'I am {"Eric"}'
'I am Eric'
>>> f'I am {'Eric'}'
File "<stdin>", line 1
f'I am {'Eric'}'
^
SyntaxError: invalid syntax
2
3
4
5
6
7
若 '
和 "
不足以满足要求,还可以使用 '''
和 """
:
>>> f"He said {"I'm Eric"}"
File "<stdin>", line 1
f"He said {"I'm Eric"}"
^
SyntaxError: invalid syntax
>>> f'He said {"I'm Eric"}'
File "<stdin>", line 1
f'He said {"I'm Eric"}'
^
SyntaxError: invalid syntax
>>> f"""He said {"I'm Eric"}"""
"He said I'm Eric"
>>> f'''He said {"I'm Eric"}'''
"He said I'm Eric"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
大括号外的引号还可以使用 \
转义,但大括号内不能使用 \
转义:
>>> f'''He\'ll say {"I'm Eric"}'''
"He'll say I'm Eric"
>>> f'''He'll say {"I\'m Eric"}'''
File "<stdin>", line 1
SyntaxError: f-string expression part cannot include a backslash
2
3
4
5
f-string 大括号外如果需要显示大括号,则应输入连续两个大括号 {{
和 }}
:
>>> f'5 {"{stars}"}'
'5 {stars}'
>>> f'{{5}} {"stars"}'
'{5} stars'
2
3
4
上面提到,f-string 大括号内不能使用 \
转义,事实上不仅如此,f-string 大括号内根本就不允许出现 \
。如果确实需要 \
,则应首先将包含 \
的内容用一个变量表示,再在 f-string 大括号内填入变量名:
>>> f"newline: {ord('\n')}"
File "<stdin>", line 1
SyntaxError: f-string expression part cannot include a backslash
>>> newline = ord('\n')
>>> f'newline: {newline}'
'newline: 10'
2
3
4
5
6
7
# 多行 f-string
f-string 还可用于多行字符串:
>>> name = 'Eric'
>>> age = 27
>>> f"Hello!" \
... f"I'm {name}." \
... f"I'm {age}."
"Hello!I'm Eric.I'm 27."
>>> f"""Hello!
... I'm {name}.
... I'm {age}."""
"Hello!\n I'm Eric.\n I'm 27."
2
3
4
5
6
7
8
9
10
# 自定义格式:对齐、宽度、符号、补零、精度、进制等
f-string 采用 {content:format}
设置字符串格式,其中 content
是替换并填入字符串的内容,可以是变量、表达式或函数等,format
是格式描述符。采用默认格式时不必指定 {:format}
,如上面例子所示只写 {content}
即可。
关于格式描述符的详细语法及含义可查阅Python 官方文档 (opens new window),这里按使用时的先后顺序简要介绍常用格式描述符的含义与作用:
# 对齐相关格式描述符
格式描述符 | 含义与作用 |
---|---|
< | 左对齐(字符串默认对齐方式) |
> | 右对齐(数值默认对齐方式) |
^ | 居中 |
# 数字符号相关格式描述符
格式描述符 | 含义与作用 |
---|---|
+ | 负数前加负号(-),正数前加正号(+) |
- | 负数前加负号(-),正数前不加任何符号(默认) |
(空格) | 负数前加负号(-),正数前加一个空格 |
注:仅适用于数值类型。
# 数字显示方式相关格式描述符
格式描述符 | 含义与作用 |
---|---|
# | 切换数字显示方式 |
注 1:仅适用于数值类型。
注 2:#
对不同数值类型的作用效果不同,详见下表:
数值类型 | 不加#(默认) | 加# | 区别 |
---|---|---|---|
二进制整数 | '1111011' | '0b1111011' | 开头是否显示 0b |
八进制整数 | '173' | '0o173' | 开头是否显示 0o |
十进制整数 | '123' | '123' | 无区别 |
十六进制整数(小写字母) | '7b' | '0x7b' | 开头是否显示 0x |
十六进制整数(大写字母) | '7B' | '0X7B' | 开头是否显示 0X |
# 宽度与精度相关格式描述符
格式描述符 | 含义与作用 |
---|---|
width | 整数 width 指定宽度 |
0width | 整数 width 指定宽度,开头的 0 指定高位用 0 补足宽度 |
width.precision | 整数 width 指定宽度,整数 precision 指定显示精度 |
注 1:0width
不可用于复数类型和非数值类型,width.precision
不可用于整数类型。
注 2:width.precision
用于不同格式类型的浮点数、复数时的含义也不同:用于 f
、F
、e
、E
和 %
时 precision
指定的是小数点后的位数,用于 g
和 G
时 precision
指定的是有效数字位数(小数点前位数+小数点后位数)。
注 3:width.precision
除浮点数、复数外还可用于字符串,此时 precision
含义是只使用字符串中前 precision
位字符。
示例:
>>> a = 123.456
>>> f'a is {a:8.2f}'
'a is 123.46'
>>> f'a is {a:08.2f}'
'a is 00123.46'
>>> f'a is {a:8.2e}'
'a is 1.23e+02'
>>> f'a is {a:8.2%}'
'a is 12345.60%'
>>> f'a is {a:8.2g}'
'a is 1.2e+02'
>>> s = 'hello'
>>> f's is {s:8s}'
's is hello '
>>> f's is {s:8.3s}'
's is hel '
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 千位分隔符相关格式描述符
格式描述符 | 含义与作用 |
---|---|
, | 使用,作为千位分隔符 |
_ | 使用_作为千位分隔符 |
注 1:若不指定 ,
或 _
,则 f-string 不使用任何千位分隔符,此为默认设置。
注 2:,
仅适用于浮点数、复数与十进制整数:对于浮点数和复数,,
只分隔小数点前的数位。
注 3:_
适用于浮点数、复数与二、八、十、十六进制整数:对于浮点数和复数,_
只分隔小数点前的数位;对于二、八、十六进制整数,固定从低位到高位每隔四位插入一个 _
(十进制整数是每隔三位插入一个 _
)。
示例:
>>> a = 1234567890.098765plain
>>> f'a is {a:f}'
'a is 1234567890.098765'
>>> f'a is {a:,f}'
'a is 1,234,567,890.098765'
>>> f'a is {a:_f}'
'a is 1_234_567_890.098765'
>>> b = 1234567890
>>> f'b is {b:_b}'
'b is 100_1001_1001_0110_0000_0010_1101_0010'
>>> f'b is {b:_o}'
'b is 111_4540_1322'
>>> f'b is {b:_d}'
'b is 1_234_567_890'
>>> f'b is {b:_x}'
'b is 4996_02d2'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 格式类型相关格式描述符
基本格式类型
格式描述符 | 含义与作用 | 适用变量类型 |
---|---|---|
s | 普通字符串格式 | 字符串 |
b | 二进制整数格式 | 整数 |
c | 字符格式,按 unicode 编码将整数转换为对应字符 | 整数 |
d | 十进制整数格式 | 整数 |
o | 八进制整数格式 | 整数 |
x | 十六进制整数格式(小写字母) | 整数 |
X | 十六进制整数格式(大写字母) | 整数 |
e | 科学计数格式,以 e 表示 ×10^ | 浮点数、复数、整数(自动转换为浮点数) |
E | 与 e 等价,但以 E 表示 ×10^ | 浮点数、复数、整数(自动转换为浮点数) |
f | 定点数格式,默认精度(precision)是 6 | 浮点数、复数、整数(自动转换为浮点数) |
F | 与 f 等价,但将 nan 和 inf 换成 NAN 和 INF | 浮点数、复数、整数(自动转换为浮点数) |
g | 通用格式,小数用 f,大数用 e | 浮点数、复数、整数(自动转换为浮点数) |
G | 与 G 等价,但小数用 F,大数用 E | 浮点数、复数、整数(自动转换为浮点数) |
% | 百分比格式,数字自动乘上 100 后按 f 格式排版,并加 % 后缀 | 浮点数、整数(自动转换为浮点数) |
常用的特殊格式类型:标准库 datetime
(opens new window) 给定的用于排版时间信息的格式类型,适用于 date
(opens new window)、datetime
(opens new window) 和 time
(opens new window) 对象
格式描述符 | 含义 | 显示样例 |
---|---|---|
%a | 星期几(缩写) | 'Sun' |
%A | 星期几(全名) | 'Sunday' |
%w | 星期几(数字,0 是周日,6 是周六) | '0' |
%u | 星期几(数字,1 是周一,7 是周日) | '7' |
%d | 日(数字,以 0 补足两位) | '07' |
%b | 月(缩写) | 'Aug' |
%B | 月(全名) | 'August' |
%m | 月(数字,以 0 补足两位) | '08' |
%y | 年(后两位数字,以 0 补足两位) | '14' |
%Y | 年(完整数字,不补零) | '2014' |
%H | 小时(24 小时制,以 0 补足两位) | '23' |
%I | 小时(12 小时制,以 0 补足两位) | '11' |
%p | 上午/下午 | 'PM' |
%M | 分钟(以 0 补足两位) | '23' |
%S | 秒钟(以 0 补足两位) | '56' |
%f | 微秒(以 0 补足六位) | '553777' |
%z | UTC 偏移量(格式是 ±HHMM[SS],未指定时区则返回空字符串) | '+1030' |
%Z | 时区名(未指定时区则返回空字符串) | 'EST' |
%j | 一年中的第几天(以 0 补足三位) | '195' |
%U | 一年中的第几周(以全年首个周日后的星期为第 0 周,以 0 补足两位) | '27' |
%w | 一年中的第几周(以全年首个周一后的星期为第 0 周,以 0 补足两位) | '28' |
%V | 一年中的第几周(以全年首个包含 1 月 4 日的星期为第 1 周,以 0 补足两位) | '28' |
# 综合示例
>>> a = 1234
>>> f'a is {a:^#10X}' # 居中,宽度10位,十六进制整数(大写字母),显示0X前缀
'a is 0X4D2 '
>>> b = 1234.5678
>>> f'b is {b:<+10.2f}' # 左对齐,宽度10位,显示正号(+),定点数格式,2位小数
'b is +1234.57 '
>>> c = 12345678
>>> f'c is {c:015,d}' # 高位补零,宽度15位,十进制整数,使用,作为千分分割位
'c is 000,012,345,678'
>>> d = 0.5 + 2.5j
>>> f'd is {d:30.3e}' # 宽度30位,科学计数法,3位小数
'd is 5.000e-01+2.500e+00j'
>>> import datetime
>>> e = datetime.datetime.today()
>>> f'the time is {e:%Y-%m-%d (%a) %H:%M:%S}' # datetime时间格式
'the time is 2018-07-14 (Sat) 20:46:02'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# lambda 表达式
f-string 大括号内也可填入 lambda 表达式,但 lambda 表达式的 :
会被 f-string 误认为是表达式与格式描述符之间的分隔符,为避免歧义,需要将 lambda 表达式置于括号 ()
内:
>>> f'result is {lambda x: x ** 2 + 1 (2)}'
File "<fstring>", line 1
(lambda x)
^
SyntaxError: unexpected EOF while parsing
>>> f'result is {(lambda x: x ** 2 + 1) (2)}'
'result is 5'
>>> f'result is {(lambda x: x ** 2 + 1) (2):<+7.2f}'
'result is +5.00 '
2
3
4
5
6
7
8
9
10