Python 字符串之格式化输出

Python 的字符串格式化传统有两种方式:%-formatting 方式以及 format 方式。除此之外,从 Python 3.6 开始映入了一种新的格式化方法:f-string,与传统格式化方法相比,f-string 不仅更易读,更简洁,不易出错,而且速度更快!本文将详解三种字符串格式化方法的用法。

% 格式符方法

% 格式符 语法规则如下:

%[(var-name)][flags][width][.precision]typecode


参数详解

[1] >>>> (var-name)

(var-name) 为命名参数,可选。用于指定 key,即用于变量映射(参数为字典) 。

[2] >>>> flags

flags 为对齐方式以及数值符号设置参数,可选。可供选择的值有:+-空格0

  • + :右对齐;正数前加正好,负数前加负号;
  • 空格:右对齐;正数前加空格,负数前加负号;
  • 0:右对齐;正数前无符号,负数前加负号,用 0 填充空白处;
  • -:左对齐;正数前无符号,负数前加负号。

[3] >>>> width

width 为显示宽度设置参数,可选。

[4] >>>> .precision

.precision 为小数点后精度设置参数,可选。

[5] >>>> typecode

typecode 为类型码参数,必选。常用类型码如下:

  • s:字符串 类型码 (采用 str() 的显示 );
  • r:字符串 类型码 (采用 repr() 的显示 );
  • d:十进制整数 类型码,将整数、浮点数转换成 进制表示;
  • i:十进制整数 类型码,将整数、浮点数转换成 进制表示;
  • o:八进制整数 类型码,将整数转换成 进制表示;
  • x:十六进制整数 类型码,将整数转换成 十六 进制表示;
  • e:指数 类型码(基底写为 e),将整数、浮点数转换成 科学计数法
  • E:指数 类型码(基底写为 E),将整数、浮点数转换成 科学计数法
  • f:浮点数 类型码,将整数、浮点数转换成 浮点数表示
  • F:浮点数 类型码,将整数、浮点数转换成 浮点数表示
  • g:指数或浮点数类型码,自动调整将整数、浮点数转换成 浮点型或科学计数法 表示,超过 6 位数用基底为 e 科学计数法;智能选择使用 %f 或 %e 格式;
  • %%:字符 “%” 类型码。

测试样例

[1] >>>> var-name

1
2
3
4
>>> name = "python"
>>> age = 20
>>> print("%(name)s:%(age)d" % {'name':name, 'age':age})
python:20

[2] >>>> flags && width

1
2
3
4
5
6
7
8
9
10
>>> name = 'python'
>>> test = 1000
>>> print("%(name)s:%(number)+10d" % {'name':name, 'number':test})
python: +1000
>>> print("%(name)s:%(number)-10d" % {'name':name, 'number':test})
python:1000
>>> print("%(name)s:%(number) 10d" % {'name':name, 'number':test})
python: 1000
>>> print("%(name)s:%(number)010d" % {'name':name, 'number':test})
python:0000001000

[3] >>>> .precision

1
2
3
4
5
>>> f = 123.321
>>> print("precision test: %(p)f" % {'p':f})
precision test: 123.321000
>>> print("precision test: %(p).2f" % {'p':f})
precision test: 123.32

[4] >>>> typecode

1
2
3
4
5
6
7
8
9
10
>>> a,b,c = 'TheMusicIsLoud', 20, 12.3
>>> print("my name is: %s; age: %d; level: %+10.4f" % (a,b,c))
my name is: TheMusicIsLoud; age: 20; level: +12.3000
>>> print("my name is: %s; age: %d; level: %-10.4f" % (a,b,c))
my name is: TheMusicIsLoud; age: 20; level: 12.3000

>>> print("%05x" % -12)
-000c
>>> print("%05o" % -12)
-0014

缺点

我们可以发现,一旦我们开始使用多个参数和更长的字符串,代码将很快变得不太容易阅读。事情已经开始显得有点凌乱:

1
2
3
4
5
6
7
first_name = "Eric"
last_name = "Idle"
age = 27
profession = "Developer"
affiliation = "Easy Python"
print(("Hello, %s %s. You are %s. You are a %s. You are a member of %s." %
(first_name, last_name, age, profession, affiliation)))

冗长,不能正确显示元组或字典都是它的缺点。


Format 方法

Python 中除了上述我们介绍过的 % 格式化方法,还可以通过 {} 和 : 来代替以前的 % 完成格式化输出,增强了字符串格式化的功能。

format 格式符语法规则如下:

[fill][align][sign][#][width][,][.precision][typecode]


参数详解

[1] >>>> fill

fill 为空白处可填充字符设置参数,可选。

[2] >>>> align

align 为对齐方式设置参数,可选,需要配和 width 参数使用。

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

[3] >>>> sign

sign 为有无符号数字设置参数,可选。

  • +:正号加正,负号加负;
  • -:正号不变,负号加负;
  • 空格:正号空格,负号加负。

[4] >>>> #

# 为是否显示进制前缀设置参数,可选。对于二进制、八进制、十六进制,如果加上 #,会显示 0b/0o/0x,否则不显示。

[5] >>>> ,

, 为数字分割符设置参数,可选。如:1,000,000

[6] >>>> width

width 为显示宽度设置参数,可选。

[7] >>>> .precision

.precision 为小数点后精度设置参数,可选。

8)typecode

typecode 为类型码参数,可选(注意这里变为可选参数)。常用类型码如下:

  • 空白:未指定类型,则默认是None,同 s

  • s:字符串 类型码 (采用 str() 的显示 );

  • r:字符串 类型码 (采用 repr() 的显示 );

  • d:十进制整数 类型码,将整数、浮点数转换成 进制表示;

  • i:十进制整数 类型码,将整数、浮点数转换成 进制表示;

  • o:八进制整数 类型码,将整数转换成 进制表示;

  • x:十六进制整数 类型码,将整数转换成 十六 进制表示;

  • e:指数 类型码(基底写为 e),将整数、浮点数转换成 科学计数法

  • E:指数 类型码(基底写为 E),将整数、浮点数转换成 科学计数法

  • f:浮点数 类型码,将整数、浮点数转换成 浮点数表示

  • F:浮点数 类型码,将整数、浮点数转换成 浮点数表示

  • g:指数或浮点数类型码,自动调整将整数、浮点数转换成 浮点型或科学计数法 表示,超过 6 位数用基底为 e 科学计数法;智能选择使用 %f 或 %e 格式;

  • %:显示百分比(默认显示小数点后 6 位) 类型码。


测试样例

[1] >>>> fill && align && width

1
2
3
4
5
6
7
8
9
>>> s1 = "{:*^20}".format('welcome')
>>> print(s1)
******welcome*******
>>> s2 = "{:*>20s}".format('welcome')
>>> print(s2)
*************welcome
>>> s3 = "{:*<20s}".format('welcome')
>>> print(s3)
welcome*************

[2] >>>> #

我们还可以通过引用其索引(或变量名称)来以任何顺序引用变量:

1
2
3
4
5
6
7
8
9
>>> a1 = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%},{:c}".format(16, 15, 14, 13, 12, 0.87623,99)
>>> a2 = "numbers: {0:#b},{0:#o},{0:#d},{0:#x},{0:#X}, {0:%},{1:c}".format(15,99)
>>> a3 = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%},{cc:c}".format(num=15,cc=99)
>>> print(a1)
numbers: 10000,17,14,d,C, 87.623000%,c
>>> print(a2)
numbers: 0b1111,0o17,15,0xf,0XF, 1500.000000%,c
>>> print(a3)
numbers: 1111,17,15,f,F, 1500.000000%,c

[3] >>>> , && .precision

1
2
3
4
5
6
>>> s1 = '{:,d}'.format(100000000)
>>> s2 = '{:.2f}'.format(123.321)
>>> print(s1)
100,000,000
>>> print(s2)
123.32

[4] >>>> 常用格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
>>> tp1 = "i am {}, age {}, {}".format("seven", 18, 'alex')
>>> tp2 = "i am {}, age {}, {}".format(*["seven", 18, 'alex'])
>>> tp3 = "i am {0}, age {1}, really {0}".format("seven", 18)
>>> tp4 = "i am {0}, age {1}, really {0}".format(*["seven", 18])
>>> tp5 = "i am {name}, age {age}, really {name}".format(name="seven", age=18)
>>> tp6 = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
>>> tp7 = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
>>> tp8 = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
>>> tp9 = "i am {:s}, age {:d}".format(*["seven", 18])
>>> tp10 = "i am {name:s}, age {age:d}".format(name="seven", age=18)
>>> tp11 = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
>>> print(tp1)
i am seven, age 18, alex
>>> print(tp2)
i am seven, age 18, alex
>>> print(tp3)
i am seven, age 18, really seven
>>> print(tp4)
i am seven, age 18, really seven
>>> print(tp5)
i am seven, age 18, really seven
>>> print(tp6)
i am seven, age 18, really seven
>>> print(tp7)
i am 1, age 2, really 3
>>> print(tp8)
i am seven, age 18, money 88888.100000
>>> print(tp9)
i am seven, age 18
>>> print(tp10)
i am seven, age 18
>>> print(tp11)
i am seven, age 18

缺点

尽管一定程度上增强了 %-formatting 功能,但当我们开始使用多个参数和更长的字符串,还是具有冗长问题:

1
2
3
4
5
6
7
first_name = "Eric"
last_name = "Idle"
age = 27
profession = "Developer"
affiliation = "Easy Python"
print("Hello, {first_name}{last_name}. You are {age}. You are a {profession}. \
You were a member of {affiliation}.".format(first_name = first_name, last_name=last_name, age=age, profession=profession, affiliation=affiliation))

f-string

Python 自 Python 3.6 开始在标准库加入一种改进 Python 格式字符串的新方法:f-string。

f-string 在功能方面不逊于传统的:%-formating 和 format 方法,同时性能又优于二者,且使用起来也更加简洁明了。故,Python3.6 及以后的版本,推荐使用 f-string 进行字符串格式化 <– 如何使用?。


Author

Waldeinsamkeit

Posted on

2018-01-06

Updated on

2023-04-03

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

Comments

You forgot to set the shortname for Disqus. Please set it in _config.yml.