Python 的字符串格式化指南

字符串格式化

Python 中控制字符串格式通常有三种形式:

  • % 占位符(格式化符)
  • str.format() 函数
  • f-string 内嵌式

Python 最先开始格式化字符串是用 %,但它的致命缺点是支持的类型有限制,只支持 int,str,double 这三种类型,从而导致其他所有类型只能转换(强制转换)为这几个类型,还有如果传递的是元组,那么必须还要传入一个单值元组,为此,添加了 str.format() 以解决 %-formatting 中的一些问题,特别是,它使用普通函数调用语法(并因此支持多个参数),并且可以通过 __format__()方法在被转换为字符串的对象上进行扩展。但 str.format() 又存在代码冗余的问题,而 f-string 提供了一种简洁易读的方式,可以在字符串中包含Python表达式的值,包括 lambda 表达式(要放在括号里面)。


% 占位符(格式化符)

格式符为真实值预留位置,并控制显示的格式

语法:

  • 字符串中占位:%[flags][width][.precision]TypeCode
  • 字符串后面传参:% 被格式化的对象

参数说明:

  • flags :可以有 + – ’ ’ 或 0

    • +:表示右对齐
    • -:表示左对齐
    • ' ':为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。
    • 0:表示使用 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)或浮点数 的形式显示(根据显示长度)

    • 占位符宽度输出

      • %20s :右对齐,占位符 20 位
      • %-20s :左对齐,占位符 20 位
      • %.3s :截取 3 位字符
      • %20.3s :20 位占位符,截取 3 位字符
      • %-10s%10s :左 10 位占位符,右 10 位占位符

实例:

  • 字符串输出

    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
    

format() 函数

  • 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-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’
    %zUTC 偏移量(格式是 ±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 (填充字符)            :<any character>
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 选项:精度

    • 对于数字对象,用来指定数字的小数位数,如果有小数;
    • 对于非数字对象,用来指定最终返回的格式化字符的最大长度,即格式化完成后,以 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 格式排版,并加 % 后缀浮点数、整数(自动转换为浮点数)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年11月2日
下一篇 2023年11月2日

相关推荐