ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

7.1 格式化字符串

Python中格式换字符串一般使用有2种方法。

一、使用%格式化表达式格式化字符串

格式化后的字符串可以使用print()打印。

>>> 'That is %d %s bird!'  %  (1, 'dead')
'That is 1 dead bird!'
>>> print('That is %d %s bird!'  %  (1, 'dead'))
That is 1 dead bird!
格式:“%typecode的字符串模板 % 元组或字典

在%操作符右侧放置一个对象(或多个对象,嵌入到元组或字典中),这些对象将会插入到左侧想让Python进行格式化字符串的一个(或多个)转换目标的位置上去。

字符码typecode

在%操作符的左侧放置一个需要进行格式化的字符串,这个字符串带有一个或多个嵌入的转换目标(%typecode),都以%开头(例如,%d)。

字符码(typecode)描述
s字符串 (或任何字符串对象) ,使用__str__ 的返回值
r类似s, 但使用 repr, 而不是__str__ 的返回值
c字符,unicode整数对应的character
d十进制 (整数)
i整数
u与 d 一样(废弃: 不再使用)
o八进制整数 (将10进制对应的数转换为八进制)
x十六进制整数
X与x一样, 但打印大写
e浮点指数,即科学记数法
E与 e 一样, 但打印大写
f浮点十进制 ,默认6位小数
F浮点十进制,同f
g自动选择浮点 e 或 f ,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学记数则是e;)
G浮点 E 或 F
%常量 %

修饰符格式说明

在%和typecode之间,可以使用修饰符:%[(key_name)][flags][width][.precision]typecode

  • 放置一个括号包裹的字典的键:(key_name)
>>> "%(n)d %(x)s" % {"n":1, "x":"spam"}
'1 spam'
  • flags罗列出左对齐(-)、显示正负号(+)和补零(0)的标位

    • + 右对齐;正数前加正号,负数前加负号;

      >>> "num: %+10.2d" % 123
      'num:       +123'
      >>> "num: % 10.2f" % -123
      'num:    -123.00'
      
    • - 左对齐(默认都是右对齐);正数前无符号,负数前加负号;

      >>> "num: %-10.2d" % 123
      'num: 123       '
      >>> "num: %-10.2f" % -123
      'num: -123.00   '
      
    • 空格 右对齐;正数前加空格,负数前加负号;

      >>> "num: % 10.2d" % 123
      'num:        123'
      >>> "num: % 10.2f" % -123
      'num:    -123.00'
      
      • 0 右对齐;正数前无符号,负数前加负号;用0填充空白处

        >>> "num: %010.2d" % 123
        'num: 0000000123'
        >>> "num: %010.2f" % -123
        'num: -000123.00'
        
  • 给出数字的整体长度和小数点后的位数等。width和percision都可以编码为一个*,以指定它们应该从输入值的下一项中取值

>>> "percent %.2f" % 99.97623
'percent 99.98'

>>> "i am %(pp).2f %%" % {"pp": 123.425556,}
'i am 123.43 %'

二、使用字符串的format()方法格式化字符串(推荐)

语法:S.format(*args, **kwargs) -> string args位置参数,kwargs关键字参数

使用主体字符串"S"作为模板,模板可以接受任意多个参数args或kwargs,这些参数表示模板中要替换的值。在主体字符串中,花括号{}作为占位符,通过位置(例如,{1})或关键字(例如,{food})指出替换目标及将要插入的参数。

{index|key:修饰}
	index:为列表的索引
	key:为字典的key
	“index(key)”与“修饰”之间冒号分隔
	修饰:[[fill]align][sign][#][0][width][,][.precision][type]

修饰符格式说明

  • fill 【可选】空白处填充的字符

  • align 【可选】对齐方式(需配合width使用)

    • <,内容左对齐
    • >,内容右对齐(默认)
    • ,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
    • ^,内容居中
  • sign 【可选】有无符号数字

  • +,正号加正,负号加负;

  • -,正号不变,负号加负;

  • ``空格` ,正号空格,负号加负;

  • # 【可选】对于二进制、八进制、十六进制,如果加上#,会显示 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位)

基本使用-示例

例1:使用位置参数

>>> "i am {}, age {}, {}".format("seven", 18, 'alex')
'i am seven, age 18, alex'
>>> "i am {}, age {}, {}".format(*["seven", 18, 'alex'])
'i am seven, age 18, alex'
>>> "i am {0}, age {1}, really {0}".format("seven", 18)
'i am seven, age 18, really seven'
>>> "i am {0}, age {1}, really {0}".format(*["seven", 18])
'i am seven, age 18, really seven'

例2:使用关键字参数

>>> "i am {name}, age {age}, really {name}".format(name="seven", age=18)
'i am seven, age 18, really seven'
>>> "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
'i am seven, age 18, really seven'

例3:同时使用关键字参数和位置参数,此时位置参数必须放在关键字参数之前

>>> template = '{motto}, {0} and {food}'
>>> template.format('ham', motto='spam', food='eggs')
'spam, ham and eggs'

例4:format主体字串中使用字典键索引、使用对象属性

>>> import sys
>>> 'My {1[spam]} runs {0.platform}'.format(sys, {'spam': 'laptop'})
'My laptop runs linux2'
>>> 'My {config[spam]} runs {sys.platform}'.format(sys=sys , config={'spam': 'laptop'})
'My laptop runs linux2'

例5:format主体字串中使用序列的索引、分片

>>> "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
'i am 1, age 2, really 3'

>>> somelist = list('SPAM')
>>> somelist
['S', 'P', 'A', 'M']
>>> 'first={0[0]}, third={0[2]}'.format(somelist)
'first=S, third=A'
>>> 'first={0}, last={1}'.format(somelist[0], somelist[-1])
'first=S, last=M'

>>> parts = somelist[0], somelist[-1], somelist[1:3]
>>> parts
('S', 'M', ['P', 'A'])
>>> 'first={0}, last={1}, middle={2}'.format(*parts) #*parts表示迭代对象parts中多个元素的位置参数
"first=S, last=M, middle=['P', 'A']"

指定格式-示例

除此以外,可以在花括号内为参数指定具体格式,使用冒号分割参数与格式:

例1:字符宽度

>>> '{0:10} is {1:10}'.format('spam', 123.4567)  #{0:10}表示第一个位置参数的字段占10个字符宽度
'spam       is   123.4567'

例2:左、右、居中对齐

>>> '{0:>10} is {1:<10}'.format('spam', 123.4567)	
'      spam is 123.4567  '

#{0:>10}表示第一个参数右对齐,占10个字符宽度;“<”表示左对齐;“^”表示居中对齐

例3:浮点类型的格式化

在格式化方法调用中,浮点数支持与%表达式中相同的类型代码和格式化声明。例如,下面的{2:g}表示,第三个参数默认地根据"g"浮点数表示格式化,{1:.2f}指定了带有2个小数位的"f"浮点数格式,{2:06.2f}添加一个6字符宽度的字段并且在左边补充0:

>>> '{0:f}, {1:.2f}, {2:06.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, 003.14'

>>> "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
'i am seven, age 18, money 88888.100000'
>>> "i am {:s}, age {:d}".format(*["seven", 18])
'i am seven, age 18'
>>> "i am {name:s}, age {age:d}".format(name="seven", age=18)
'i am seven, age 18'
>>> "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
'i am seven, age 18'
>>> "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
'numbers: 1111,17,15,f,F, 1587.623000%'
>>> "numbers: {:b},{:o},{:d},{:x},{:X}, {:10.2%}".format(15, 15, 15, 15, 15, 15.87623, 2)
'numbers: 1111,17,15,f,F,   1587.62%'
>>> "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
'numbers: 1111,17,15,f,F, 1500.000000%'
>>> "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
'numbers: 1111,17,15,f,F, 1500.000000%'

>>> 'num:{:0>+#15.2f}'.format(123.4)
'num:00000000+123.40'
>>> 'num:{:0<+#15.2f}'.format(123.4)
'num:+123.4000000000'
>>> 'num:{:0<+15,.2f}'.format(123456.789)
'num:+123,456.790000'

例4:逗号实现数字的千分位分割

>>> '{0:,d}'.format(999999999999999999)
'999,999,999,999,999,999'

例5:参数嵌套

格式化参数可以在格式化字符串中硬编码,或者通过嵌套的格式化语法从参数列表动态地获取

>>> '{0:.{1}f}'.format(1 / 3.0, 4)
'0.3333'

三、%表达式和format()方法的区别

  1. format()方法支持不同进制编码和千分位分组,支持直接的键和属性引用。
>>> '{0:b}'.format(255)
'11111111'
>>> '{0:o}'.format(255)
'377'
>>> '{0:x}'.format(255)
'ff'
  1. format()方法使用位置参数或关键字参数,更加易读。但是如果使用自动相对计数,则会降低易读性。
>>> 'The {} side {} {}'.format('bright', 'of', 'life')
'The bright side of life'
  1. 使用格式化表达式,单个值可以独自给定,但多个值必须放入一个元组中。如果要将元祖放置到字符串中,需要使用元祖嵌套。