Python 中控制字符串格式通常有三种形式:
Python 最先开始格式化字符串是用 %,但它的致命缺点是支持的类型有限制,只支持 int,str,double 这三种类型,从而导致其他所有类型只能转换(强制转换)为这几个类型,还有如果传递的是元组,那么必须还要传入一个单值元组,为此,添加了 str.format() 以解决 %-formatting 中的一些问题,特别是,它使用普通函数调用语法(并因此支持多个参数),并且可以通过 __format__()
方法在被转换为字符串的对象上进行扩展。但 str.format() 又存在代码冗余的问题,而 f-string 提供了一种简洁易读的方式,可以在字符串中包含Python表达式的值,包括 lambda 表达式(要放在括号里面)。
格式符为真实值预留位置,并控制显示的格式
语法:
%[flags][width][.precision]TypeCode
参数说明:
flags :可以有 + - ’ ’ 或 0
+
:表示右对齐-
:表示左对齐' '
:为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。width:表示显示宽度
precision:表示小数点后精度
TypeCode:类型码,用以控制显示的类型
%s :以 字符串 的形式显示(采用 str() 的显示)
%r :以 字符串 的形式显示(采用 repr() 的显示)
%c :以 单个字符 的形式显示(传参多个字符会报错)
%b :以 二进制整数 的形式显示
%d :以 十进制整数 的形式显示
%i :以 十进制整数 的形式显示
%o :以 八进制整数 的形式显示
%x :以 十六进制整数 的形式显示
%f :以 浮点数 的形式显示,保留小数点后面六位有效数字
%.2f :保留 2 位小数
%F :以 浮点数 的形式显示,与上相同
%e :以 指数 的形式显示(基底写为 e),保留小数点后面六位有效数字
%.2e :保留 2 位小数位,使用科学计数法
%E :以 指数 的形式显示(基底写为 E)
%g :以 指数(e)或浮点数 的形式显示
根据显示长度,在保证六位有效数字的前提下,使用小数方式,否则使用科学计数法
%G :以 指数(E)或浮点数 的形式显示(根据显示长度)
占位符宽度输出
实例:
字符串输出
print('hi! %s!' %('Echohye')) # 如果只有一个数,%后面可以不加括号,如print('hi! %s!'%'Echohye')
# 输出:hi! Echohye!
print('hi! %20s!' % 'Echohye') # 占位符宽度输出
# 输出:hi! Echohye!
name = 'Echohye'
print('hi! %s' %(name))
# 输出:hi! Echohye
id = '123'
print('%s的id是%s' %(name, id))
# 输出:Echohye的id是123
整数输出
print('今年%d岁了' %(20))
# 输出:今年20岁了
print('%e'%1.11111)
# 输出:1.111110e+00
print('%.2e'%1.11111)
# 输出:1.11e+00
print('%g'%1.2345678)
# 输出:1.23457
print('%.2g'%1.2345678)
# 输出:1.2
浮点数输出
print('%f' %1.2345)
# 输出:1.234500
print('%.2f' %1.2345)
# 输出:1.23
Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能
基本语法是通过 {} 和 : 来代替以前的 %
format() 函数可以接受不限个参数,位置可以不按顺序
不带编号,即 “{}”,按默认顺序
带序号占位,可调换顺序,即 “{1}”、“{2}”
带名称占位,即 “{a}”、“{tom}”
注:序号占位和名称占位可以混用,但一般不推荐
实例:
字符串输出
# 不设置指定位置,按默认顺序
print("{} {}!".format("hello", "Echohye"))
# 输出:'hello Echohye!'
# 设置指定位置,序号占位符
print("{0} {1}!".format("hello", "Echohye"))
# 输出:'hello Echohye!'
print("{1} {0}!".format("hello", "world"))
# 输出:'Echohye hello!'
# 设置指定位置,名称占位符
print("{b} {a}!".format(a="hello", b="world"))
# 输出:'Echohye hello!'
# 通过字典设置参数
site = {"name": "Echohye", "wxNum": "Echo_hyee"}
print("名字:{name}, 微信号:{wxNum}".format(**site)) # **不能落下
# 通过列表索引设置参数
list = ['Echohye', 'Echo_hyee']
print("名字:{0[0]}, wxNum:{0[1]}".format(list)) # “0”不能落下
list = [['Echohye', 'Echo_hyee'],['小二', '12345']]
print("名字:{0[0]}, wxNum:{0[1]}".format(list))
# 输出:名字:['Echohye', 'Echo_hyee'], wxNum:['小二', '12345']
print("名字:{0[1][0]}, wxNum:{0[1][1]}".format(list))
# 输出:名字:小二, wxNum:12345
print("名字:{0[0]}, wxNum:{0[1]}".format(list[0]))
# 输出:名字:Echohye, wxNum:Echo_hyee
整数输出
print('{}'.format(1314))
# 输出:1314
print('{:.0f}'.format(1314.22)
# 输出:1314
浮点数输出
# 保留小数后两位
print('{:.2f}'.format(3.1415926))
# 输出:3.14
# 带符号保留小数后两位,+ 表示在正数前显示 +,在负数前显示 -
print('{:+.2f}'.format(3.1415926))
# 输出:+3.14
print('{:+.2f}'.format(-3.1415926))
# 输出:-3.14
# 不带小数
print('{:.0f}'.format(3.1415926)) # “0”不能省
# 输出:3
占位符宽度输出
# 空格补x,填充左边,宽度为10
# 说明:x只能是指定一个字符,不可以多位,可以是任何字符,默认为空格
print('{:x>10s}'.format('happy'))
# 输出:xxxxxhappy
# 空格补x,填充右边,宽度为10
print('{:x<10s}'.format('happy'))
# 输出:happyxxxxx
# 空格补x,填充两边,宽度为10
print('{:x^10s}'.format('happy'))
# 输出:xxhappyxxx # 如果占位符数是奇数,则右边多于左边
其它格式
# 以逗号分隔的数字格式
print('{:,}'.format(999999999))
# 输出:999,999,999
# 百分比格式
print('{:%}'.format(0.99999)) # 默认仍是六位小数
# 输出:99.999000%
print('{:.2%}'.format(0.99999)) # 大于显示的位数则四舍五入
# 输出:100.00%
print('{:.2%}'.format(0.9999))
# 输出:99.99%
# 指数记法
print('{:.0e}'.format(1000000))
# 输出:1e+06
print('{:.2e}'.format(1000000))
# 输出:1.00e+06
print('{:.2e}'.format(0.1000000))
# 输出:1.00e-01
print('{:.2e}'.format(0.000001))
# 输出:1.00e-06
f-string 内嵌式:标注了 'f'
或 'F'
前缀的字符串字面值,可包含替换字段,即以 {}
标注的表达式
f-string 内嵌式在运行时计算并且使用 format() 函数进行格式化。用法跟 str.format() 差不多,但 f-string 更加简洁、方便、高效。
常见使用方式:
基本使用:f-string用大括{ }表示被替换字段,其中直接填入替换内容即可
# 字符串输入
print(f"my name is {'Echohye'}") # 这里得注意""和''的嵌套了
# 参数代入
name = 'Echohye'
print(f'my name is {name}')
# 输出:my name is Echohye
表达式求值与函数调用:
f-string 的大括号 { } 可以填入表达式或调用函数,Python 会求出其结果并填入返回的字符串内
print(f"They have {2+5*2} apples") # 输出:They have 12 apples
name = "Huang Wei"
print(f"my name is {name.lower()}") # 输出:my name is huang wei
f-string 中使用 lambda 匿名函数:可以做复杂的数值计算
注:注意语法格式的写法,第一个小括号表示的是 lambda 表达式,第二个小括号表示给 lambda 表达式传入参数。
aa = 123.456
print(f"{(lambda x:x*5-2)(aa):.2f}") # 输出:615.28
bb = 8
cc = 2
print(f"{(lambda x,y:x+y)(bb,cc)}") # 输出:10
f-string 中引号使用存在的问题
f-string 大括号内使用的引号不能和大括号外的引号(定界符引号)冲突,需根据情况灵活切换使用单引号、双引号、单三引号、双三引号
注意:只要大括号内外的引号不同,就没有问题。但是大括号中只能是单引号和双引号 ,大括号外的引号(定界符引号)可以使用单引号、双引号、单三引号、双三引号。
大括号外定界符引号内的引号还可以使用 \ 符号转义,但大括号内不能使用 \ 符号转义
print(f"he\'ll go to {'shang hai'}") # 输出:he'll go to shang hai
f-string 中大括号使用存在的问题
想要在 f-string 中打印{}
时, 需要使用双大括号 {{}} , 此时双括号内部的内容将不会被渲染
print(f"5{'{apples}'}") # 输出:5{apples}
print(f"5{{'apples'}}") # 输出:5{'apples'}
print(f"{{5}}{'apples'}") # 输出:{5}apples
时间格式化
常用的特殊格式类型:标准库 datetime 给定的用于排版时间信息的格式类型,适用于 date、datetime 和 time 对象
import datetime
e = datetime.datetime.today()
f'the time is {e:%Y-%m-%d %H:%M:%S}' # 输出:the time is 2023-08-17 11:05:06
格式描述符 | 含义 | 显示样例 |
---|---|---|
%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’ |
详细语法格式:
[[fill]align][sign][#][0][width][grouping_option][.precision][type]
# 选项:
fill (填充字符) :
align (对齐方式) :"<" ,">","=","^"
sign (数字标记) :"+","-"," "
width (最小字段宽度) :任意正数
grouping_option (数值分隔符号) :"_",","
precision (准确率) :任意正数
type (类型) :"b","c","d","e","E","f","F", "g","G","n","o","s","x", "X","%"
fill 选项:填充字符
align 选项:对齐方式
<
:左对齐(字符串默认对齐方式)>
:右对齐(数值默认对齐方式)=
:填充时强制在正负号与数字之间进行填充,只支持对数字的填充^
:表示居中注:
除非定义了最小字段宽度(width 选项),否则字段宽度将始终与填充它的数据大小相同,对齐选项也就没有意义。
如果指定了 align 值,则可以在其前面加上可以是任何字符的填充字符,缺省则默认为空格。
无法使用文字大括号(“{”或“}”)作为格式化字符串文字中的填充字符或使用 str.format() 方法。 但是,可以插入带有嵌套替换字段的大括号。
示例:
print(f'{"zhangsan":^18}') # 输出: zhangsan
print(f'{"zhangsan":a^18}') # 输出:aaaaazhangsanaaaaa
sign 选项:描述符。此选项仅对数值有效
+
:强制对数字使用正负号-
:仅对负数使用前导负号(默认使用)示例:
print(f'{199:+}') # 输出:+199
#
选项:换数字显示方式,用于控制是否显示进制前缀。此选项仅对 integer(整形),float,complex 类型有效。
对于不同类型,替代形式的定义不同。:
对于整数,当使用二进制,八进制或十六进制输出时,此选项将前缀 “0b”,“0o” 或 “0x” 添加到输出值。
对于浮点数,复数和十进制,替换形式会导致转换结果始终包含小数点字符,即使后面没有数字也是如此。
通常,只有在跟随数字的情况下,这些转换的结果中才会出现小数点字符。
此外,对于 “g” 和 “G” 转换,不会从结果中删除尾随零
# b:二进制
print(f"{10:b}") # 输出:1010
print(f"{10:#b}") # 输出:0b1010
grouping_option 选项:对数字整数部分进行千分位分隔
可选值:
,(逗号):使用 , 作为千分位分隔符
仅适用于浮点数、复数与十进制整数。对于浮点数和复数,只分隔小数点前的数位
_
(下划线):使用 _
作为千分位分隔符
适用于浮点数、复数与二、八、十、十六进制整数:
_
只分隔小数点前的数位;_
(十进制整数是每隔三位插入一个 _)示例:
money = 19999999877
print(f'{money:,}') # 输出:19,999,999,877
print(f'{money:_}') # 输出:19_999_999_877
width 选项:指定最小字段的宽度,十进制整数。若未指定则字段宽度由内容来确定
precision 选项:精度
对于精确率的使用 详见:python - sklearn 计算精准率(Precision)
浮点数格式化示例:
# 前导0、统一宽度右对齐、千分位、小数点后固定位数、百分比
a = 48424174
print(f"{a:012.2f}:{a:12.3f}:{a:12,.2f}:{a:12.1%}")
# 输出:000004842.42: 4842.417: 4,842.42: 484241.7%
type 选项:指定字符:\A 如果指定的字符位于字符串的开头,则返回匹配项
基本格式类型:
格式描述符 | 含义与作用 | 适用变量类型 |
---|---|---|
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 格式排版,并加 % 后缀 | 浮点数、整数(自动转换为浮点数) |