Python基础必掌握的字符串格式化操作详解

学Python数据科学,玩游戏、学日语、搞编程一条龙。

整套学习自学教程中应用的数据都是《三國志》、《真·三國無雙》系列游戏中的内容。

Python 来格式化字符串有 .format() 字符串方法f-string 方法
在这里插入图片描述

字符串.format() 方法

Python 2.6版本引入了字符串 .format() 方法。

调用模式有固定的模板,<positional_arguments><keyword_arguments> 指定插入的值 <template> 以代替替换的字段。

生成的格式化字符串是方法的返回值。

<template>.format(<positional_argument(s)>, <keyword_argument(s)>)

<template> 字符串中,替换字段用大括号 ( {} ) 括起来。

'{
    
    { {} }}'.format('曹操')
'{ 曹操 }'

字符串.format() 参数

位置参数,字符串模运算符和 string.format() 方法。

print('%d 天需要造%s %.2f 万支' % (3, '箭', 10.0))
3 天需要造箭 10.00 万支

print('{0} 天需要造{1} {2} 万支'.format(3, '箭', 10.0))
3 天需要造箭 10.0 万支

<template> 进行数据格式化示意图。
在这里插入图片描述
位置参数被插入到模板中以代替编号的替换字段。

'{0}/{1}/{2}'.format('曹操', '孫権', '劉備')
'曹操/孫権/劉備'

替换字段可以按任何顺序指定出现在模板中,并且可以出现多次。

'{2}.{1}.{0}/{0}{0}.{1}{1}.{2}{2}'.format('曹操', '孫権', '劉備')
'劉備.孫権.曹操/曹操曹操.孫権孫権.劉備劉備'

超出范围的替换字段编号时会出现错误。

'{3}'.format('曹操', '孫権', '劉備')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

自动字段编号和参数不匹配时的情况。

# 字符串数量 < 编号数量
'{}{}{}{}'.format('曹操','孫権','劉備')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

# 字符串数量 > 编号数量
'{}{}'.format('曹操', '孫権', '劉備')
'曹操孫権'

两种方法不可以混合使用。

'{1}{}{0}'.format('曹操','孫権','劉備')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: cannot switch from manual field specification to automatic field numbering

关键字参数,关键字参数被插入到模板字符串中,以代替具有相同名称的关键字替换字段。

使用关键字参数格式化输出。

print('{num_day} 天需要造{item} {num_item} 万支'.format(
	num_day = 3, 
	item = '箭', 
	num_item = 10.0
))

在这里插入图片描述
缺少关键字会出现错误。

'{x}/{y}/{w}'.format(x='曹操', y='孫権', z='劉備')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'w'

按任意顺序指定关键字参数。

'{0}/{1}/{2}'.format('曹操', '孫権', '劉備')
'曹操/孫権/劉備'
'{0}/{1}/{2}'.format('孫権', '劉備', '曹操')
'孫権/劉備/曹操'
'{x}/{y}/{z}'.format(x='曹操', y='孫権', z='劉備')
'曹操/孫権/劉備'
'{x}/{y}/{z}'.format(y='孫権', z='劉備', x='曹操')
'曹操/孫権/劉備'

位置参数必须出现在任何关键字参数之前。

'{0}{x}{1}'.format('曹操', '孫権', x='劉備')
'曹操劉備孫権'

'{0}{x}{1}'.format('曹操', x='劉備', '孫権')
  File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument

指定变量方法进行输出。

x = '曹操'
y = '孫権'
z = '劉備'
'{0}/{1}/{s}'.format(x, y, s=z)
'曹操/孫権/劉備'

字符串.format() 直接替换字段

调用 Python 的.format()方法时 <template> 字符串包含替换字段。这些指示在模板中将参数插入方法的位置。

替换字段由三个部分组成。

"""
{[<name>][!<conversion>][:<format_spec>]}
<name>	指定要格式化的值的来源
<conversion>	指示用于执行转换的标准 Python 函数
<format_spec>	指定有关如何转换值的更多详细信息
"""

<name>组件,由位置参数的数字,或者是关键字参数的关键字组成。

x, y, z = 1, 2, 3
'{0}, {1}, {劉備}'.format(x, y, 劉備=z)
'1, 2, 3'

参数是列表访问列表的元素。

list_ = ['曹操', '孫権', '劉備']
'{0[0]}, {0[2]}'.format(list_)
'曹操, 劉備'
'{my_list[0]}, {my_list[2]}'.format(my_list=list_ )
'曹操, 劉備'

参数是字典访问字典的元素。

dict_ = {
    
    'key1': '曹操', 'key2': '孫権'}
dict_['key1']
'曹操'
'{0[key1]}'.format(dict_)
'曹操'
dict_ ['key2']
'孫権'
'{my_dict[key2]}'.format(my_dict=dict_ )
'孫権'

参数是对象访问对象的属性。

z = 3+5j
type(z)
<class 'complex'>
z.real
3.0
z.imag
5.0

z
(3+5j)
'real = {0.real}, imag = {0.imag}'.format(z)
'real = 3.0, imag = 5.0'

<conversion>组件,数据强制转换 str() 强制转换方法。

'{0!s}'.format(42) # !s	转换为str()
'42'
'{0!r}'.format(42) # !r	转换为repr()
'42'
'{0!a}'.format(42) # !a	转换为ascii()
'42'

<format_spec>组件,包含的信息可以很好地控制在插入模板字符串之前如何格式化值。

"""
:[[<fill>]<align>][<sign>][#][0][<width>][<group>][.<prec>][<type>]
"""

<align>组件,控制如何在指定的字段宽度内填充和定位格式化输出,这些子组件只有在格式化的字段值不占据整个字段宽度时才有意义。

# 小于号 (<) 的值表示输出是左对齐的
'{0:<8s}'.format('曹操')
'曹操     '
'{0:<8d}'.format(123)
'123     '

# 大于号(>)的值表示输出应右对齐
'{0:>8s}'.format('曹操')
'     曹操'
'{0:>8d}'.format(123)
'     123'

# 符号(^)的值表示输出应位于输出字段的中心
'{0:^8s}'.format('曹操')
'  曹操   '
'{0:^8d}'.format(123)
'  123   '

# 符号(=)为<align>子组件指定一个值
'{0:+8d}'.format(123)
'    +123'
'{0:=+8d}'.format(123)
'+    123'
'{0:+8d}'.format(-123)
'    -123'
'{0:=+8d}'.format(-123)
'-    123'

<fill> 组件,指定当格式化的值没有完全填满输出宽度时如何填充额外的空间。

'{0:->8s}'.format('曹操')
'-----曹操'
'{0:#<8d}'.format(123)
'123#####'
'{0:*^8s}'.format('曹操')
'**曹操***'

<sign>组件,控制符号是否与组件一起出现在数字输出。

# 加号 (+) 正负值始终都包含一个符号。
'{0:+6d}'.format(123)
'  +123'
'{0:+6d}'.format(-123)
'  -123'

# 单个空格 (' ') 表示负值包含符号。
'{0:*> 6d}'.format(123)
'** 123'
'{0:*>6d}'.format(123)
'***123'
'{0:*> 6d}'.format(-123)
'**-123'

# 组件,哈希字符 ( # ) 会导致在值左侧包含显式基本指示符。

# 对于二进制、八进制和十六进制表示类型
'{0:b}, {0:#b}'.format(16)
'10000, 0b10000'
'{0:o}, {0:#o}'.format(16)
'20, 0o20'
'{0:x}, {0:#x}'.format(16)
'10, 0x10'

# 对于浮点或指数表示类型
'{0:.0f}, {0:#.0f}'.format(123)
'123, 123.'
'{0:.0e}, {0:#.0e}'.format(123)
'1e+02, 1.e+02'

0 组件,如果输出小于指定的字段宽度,并且指定数字零 ( 0 ),则值将在左侧填充零而不是 ASCII 空格字符。

'{0:05d}'.format(123)
'00123'
'{0:08.1f}'.format(12.3)
'000012.3'
# 适用于字符串值。
'{0:>06s}'.format('曹操')
'000曹操'

<width>组件,指定输出字段的最小宽度。

'{0:8s}'.format('曹操')
'曹操     '
'{0:8d}'.format(123)
'     123'
# 指定的值比最小值长则忽略。
'{0:2s}'.format('曹操孫権')
'曹操孫権'

<group>组件,在数字输出中包含分组分隔符,可以指定为逗号字符 ( , ) 或下划线字符 ( _ )。

'{0:,d}'.format(1234567)
'1,234,567'
'{0:_d}'.format(1234567)
'1_234_567'
'{0:,.2f}'.format(1234567.89)
'1,234,567.89'
'{0:_.2f}'.format(1234567.89)
'1_234_567.89'

# 二进制、八进制和十六进制表示类型指定。
'{0:_b}'.format(0b111010100001)
'1110_1010_0001'
'{0:#_b}'.format(0b111010100001)
'0b1110_1010_0001'
'{0:_x}'.format(0xae123fcc8ab2)
'ae12_3fcc_8ab2'
'{0:#_x}'.format(0xae123fcc8ab2)
'0xae12_3fcc_8ab2'

.<prec>组件,指定浮点表示类型的小数点后的位数。

'{0:8.2f}'.format(1234.5678)
' 1234.57'
'{0:8.4f}'.format(1.23)
'  1.2300'
'{0:8.2e}'.format(1234.5678)
'1.23e+03'
'{0:8.4e}'.format(1.23)
'1.2300e+00'
# 对于字符串类型,.<prec>指定转换输出的最大宽度
'{:.4s}'.format('曹操孫権')
'曹操b'

<type>组件,表示字符的转换类型。

"""
b	二进制整数
c	单个字符
d	十进制整数
e、E	指数的
f、F	浮点
g、G	浮点数或指数
o	八进制整数
s	细绳
x、X	十六进制整数
%	百分比
"""

'%d' % 42
'42'
'{:d}'.format(42)
'42'

'%f' % 2.1
'2.100000'
'{:f}'.format(2.1)
'2.100000'

'%s' % '曹操孫権'
'曹操孫権'
'{:s}'.format('曹操孫権')
'曹操孫権'

'%x' % 31
'1f'
'{:x}'.format(31)
'1f'

.format() 中表示类型和字符串模运算符转换类型之间存在一些细微差。

# 类型 b 字符串格式化差异,类型 i,u 字符串格式化差异。
# 二进制整数转换
'{:b}'.
format(257)
'100000001'

# 模运算符,不支持
'%b' % 257
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unsupported format character 'b' (0x62) at index 1

# 类型 c 字符串格式化差异。
# 模运算符允许具有转换类型的整数或单个字符值
'%c' % 35
'#'
'%c' % '#'
'#'

# 要求表示类型对应的值c是整数
'{:c}'.format(35)
'#'
'{:c}'.format('#')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'c' for object of type 'str'


# 类型 g, G 字符串格式化差异。
'{:g}'.format(3.14159)
'3.14159'
'{:g}'.format(-123456789.8765)
'-1.23457e+08'
'{:G}'.format(-123456789.8765)
'-1.23457E+08'


# 类型 r, a 字符串格式化差异,分别强制转换 **repr()** 和 **ascii()** 。
repr({
    
    1: 4, 2: 5})  # '{1: 4, 2: 5}'	
repr(tuple)  # "<class 'tuple'>"
repr("string")  # "'string'"
repr("我是 ascii")  # '我是 ascii'
ascii({
    
    1: 4, 2: 5})  # '{1: 4, 2: 5}'
ascii(tuple)  # "<class 'tuple'>"
ascii("string")  # "'string'"
ascii("我是 ascii")  # "'\\u6211\\u662f ascii'"


# 类型 % 字符串格式化差异,使用带模运算符的%转换类型在输出中插入文字 **%** 字符。
'%f%%' % 65.0
'65.000000%'
'{:%}'.format(0.65)
'65.000000%'

字符串.format() 嵌套替换字段

将关键字参数与嵌套替换字段一起使用。

w = 10
p = 2
'{val:{wid}.{pr}f}'.format(wid=w, pr=p, val=123.456)
'    123.46'

分组字符<group>是嵌套的 。

'{0:{grp}d}'.format(123456789, grp='_')
'123_456_789'
'{0:{grp}d}'.format(123456789, grp=',')
'123,456,789'

格式化字符串文字(f-String)

f 字符串语法

# f-string看起来很像一个典型的 Python 字符串
f'曹操 孫権 劉備'
'曹操 孫権 劉備'

# 可以使用大写字母F
s = F'曹操 孫権 劉備'
s
'曹操 孫権 劉備'

# 表达式嵌套处理
s = '孫権'
print(f'曹操.{
      
      s}.劉備')
曹操.孫権.劉備

# 转义序列处理
s = '孫権'
print(f'曹操\n{
      
      s}\n劉備')
曹操
孫権
劉備

嵌入在 f 字符串不同的意义

# 变量
num_day,item,num_item = 3,'箭',10.0
f'{
      
      num_day} 天需要造{
      
      item} {
      
      num_item} 万支'
'3 天需要造箭 10.0 万支'

# 算术表达式
num_day,item,num_item = 3,'箭',10.0
f'每天需要造{
      
      item} {
      
      num_item/num_day} 万支'
'每天需要造箭 3.3333333333333335 万支'

# 复合类型的对象
a = ['曹操', '孫権', '劉備']
d = {
    
    '曹操': 1, '孫権': 2}
print(f'a = {
      
      a} | d = {
      
      d}')
"a = ['曹操', '孫権', '劉備'] | d = {'曹操': 1, '孫権': 2}"

# 索引、切片和关键引用
a = ['曹操', '孫権', '劉備']
d = {
    
    '曹操': 1, '孫権': 2}
print(f'{
      
      a[0]}')
曹操
print(f'{
      
      a[-2:]}')
['孫権', '劉備']
print(f'{
      
      a[::-1]}')
['劉備', '孫権', '曹操']
print(f"{
      
      d['孫権']}")
2

# 函数和方法调用
a = ['曹操', '孫権', '劉備']
print(f' {
      
      len(a)} items')
3 items

# 条件表达式
age = 29
f'諸葛亮  {
      
      "已出山" if age > 27 else "未出山"}。'
'諸葛亮  已出山。'

# 对象属性
z = 3+5j
z
(3+5j)
print(f'real = {
      
      z.real}, imag = {
      
      z.imag}')
real = 3.0, imag = 5.0

# 转义操作
z = '孫権'
print(f'曹操\n{
      
      z}\n劉備')
曹操
孫権
劉備
print(rf'曹操\n{
      
      z}\n劉備')
曹操\n孫権\n劉備
print(fr'曹操\n{
      
      z}\n劉備')
曹操\n孫権\n劉備

# 模板.format()
z = '曹操孫権'
f'{
     
     { {
      
      z[::-1]} }}'
'{ 権孫操曹 }''

f-String 表达式限制

# f-string 表达式不能为空
f'曹操{}孫権'
  File "<stdin>", line 1
SyntaxError: f-string: empty expression not allowed

# f 字符串表达式不能包含反斜杠 ( \ ) 字符。
print(f'曹操{
      
      \n}孫権')
  File "<stdin>", line 1
SyntaxError: f-string expression part cannot include a backslash
print(f'曹操{
      
      \'}孫権')
  File "<stdin>", line 1
SyntaxError: f-string expression part cannot include a backslash

# 创建一个包含要插入的转义序列的临时变量来绕过此限制
nl = '\n'
print(f'曹操{
      
      nl}孫権')
曹操
孫権
quote = '\''
print(f'曹操{
      
      quote}孫権')
曹操'孫権

# 三引号的 f 字符串中的表达式不能包含注释
z = '孫権'

print(f'''曹操{
      
      
... z
... }劉備''')
曹操孫権劉備

print(f'''曹操{
      
      
... z    # Comment
... }''')
  File "<stdin>", line 3
SyntaxError: f-string expression part cannot include '#'

f 字符串格式

# 所有适用的< format_spec > 组件.format()也适用于 f 字符串。
n = 123
'{:=+8}'.format(n)
'+    123'
f'{
      
      n:=+8}'
'+    123'

s = '曹操'
'{0:*^8}'.format(s)
'**曹操***'
f'{
      
      s:*^8}'
'**曹操***'

n = 0b111010100001
'{0:#_b}'.format(n)
'0b1110_1010_0001'
f'{
      
      n:#_b}'
'0b1110_1010_0001'


# 嵌套使用 Python.format()方法的嵌套替换字段
a = ['曹操', '孫権', '劉備']
w = 4
f'{
      
      len(a):0{
      
      w}d}'
'0003'

猜你喜欢

转载自blog.csdn.net/qq_20288327/article/details/124515322