打印格式化,利用这些方法可以让程序的输出看起来与你希望的一样。我们将要了解下面的内容:
- 换行(以及什么时候换行)。
- 水平间隔(以及按列对齐)。
- 在字符串中间打印变量。
- 以整数、小数或E记法格式打印数字,以及设置应当有多少个小数位。
以上应该已经涵盖了程序中需要的 99% 的功能。
换行
print('Hi')
print('There')
Hi
There
除非你另外指出,否则 Python 每次执行 print
时都会在新的一行上开始。打印 Hi
之后,Python 会下移一行,并回到第一列来打印 There
。Python 会在两个词之间插入一个换行符(newline)。换行符的作用相当于在文本编辑器中按下了回车。
print('Hi', end = ' ')
print('there')
Hi there
#------------------------
print('Hi')
print()
print('there')
Hi
there
特殊代码
增加换行符还有一种方法。Python 提供了一些特殊的代码,可以把这些代码增加到字符串中,以不同的方式打印。这些特殊的打印代码都以一个反斜线(\
)字符开头。换行符的相应代码是 \n
:
print("Hello World")
Hello World
print("Hello \nWorld")
Hello
World
print('Hi \nthere')
Hi
there
\n
使 Hello
和 World
分别打印在不同的行上,因为它在这两个词之间增加了一个换行符。
如果字符串里面有很多字符都需要转义,就需要加很多 \
,为了简化,Python 还允许用 r''
表示 ''
内部的字符串默认不转义,可以自己试试:
>>> print('\\\t\\')
\ \
>>> print(r'\\\t\\')
\\\t\\
制表符
制表符(Tab, 也叫做进格符)在按列对齐方面非常有用。要了解制表符是如何工作的,可以想一想屏幕上的每一行都划分为多个大小相同的块时是什么样。下面假设每一个块为 8
个字符宽。插人一个制表符时,就会移到下一个块开始的位置。
制表符的特殊代码是 \t
,要了解具体怎么做,最好的办法就是试一试。
print('ABC\t\tXYZ')
ABC XYZ
XYZ
与 ABC
有几个字符的间隔。实际上,XYZ
距离这一行的起始位置正好是 8
个字符。这是因为块的大小是 8。也可以这样讲:每 8 个字符之后有一个制表点(tab stop)。
print('ABC\t\tXYZ')
print('ABCDE\t\tXYZ')
print('ABCEDFG\t\tXYZ')
ABC XYZ
ABCDE XYZ
ABCEDFG XYZ
可以将屏幕(或者每-行)视为按 8
个空格为一块来摆放。注意,尽管 ABC
序列越来越长,但 XYZ
仍保持在原来的位置上。\t
告诉 Python 让 XYZ
从下一个制表点开始,或者从下一个可用的块开始。不过,一旦 ABC
序列长到将第一块填满,Python 就会把 XYZ
下移到下一个制表点。
按列组织内容时,制表符很有用,能让所有内容都对齐。下面就要利用这一点以及我们了解的关于循环的知识,打印一个关于正方形和立方体的表格:
print("Number\tSquare\tCube")
for i in range(1, 11):
print('%d\t\t%d\t\t%d' % (i, i**2, i**3))
Number Square Cube
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
反斜线
由于反斜线字符 \
用来表示特殊打印代码,如果我们确实想打印一个 \
字符,而不是将其作为代码的一部分打印,该如何告诉 Python 呢?我们的技巧是把两个反斜线放在一起:
print('hi\\there')
hi\there
第一个 \
告诉 Python 接下来是一些特殊的内容,第二个 \
告诉 Python 这些特殊的内容就是 \
字符。
百分号
百分号(%)对格式字符串来说是一个特殊的字符,那么怎么打印 %
呢?
Python 有时候很聪明,它能确定你什么时候使用号符号开始一个格式字符串,以及什么时候只是想打印一个百分号:
>>> print('I got 90% on my math test!')
I got 90% on my math test!
在这个例子中,字符串外面没有第二个号,也没有需要格式化的变量,所以 Python 认为这个 %
只是字符串中的一个普通字符。
但是如果你在打印格式化字符串时想打印一个百分号,就需要输人两个百分号,就像你曾经用两个反斜线来打印一一个反斜线一样。我们说第一个百分号对第二个百分号进行了转义:
>>> math = 75.4
>>> print('I got %.2f%% on my math test' % math)
I got 75.4% on my math test
第一个 %
表示格式化字符串。两个号在一起告诉 Python,你希望打印出一个 %
字符。引号外面的 %
告诉Python 你需要将后面的变量打印出来。
插入变量
假设希望在 print
语句中间插入一个字符串变量,我们可以使用格式字符串(format string
),其中使用了
百分号(号):
name = 'Warren Sande'
book = 'Sky'
print('My name is %s and I wrote this book %s' % (name, book))
My name is Warren Sande and I wrote this book Sky
这里有两处用到号符号。先是用在字符串中间,指示要把变量放在什么位置。然后在字符串后面再次用到,告诉Python 接下来就是我们]希望在字符串中插入的变量。%s
表示我们想插入一个字符串变量。如果想插人整数,要使用 %i
;想插入浮点数,则要使用 %f
。
%s
、%f
和 %i
都称为格式字符串,这些代码用来指示如何显示变量。格式字符串中还可以增加一些其他内容,从而完全按你希望的方式打印数字。还可以使用一些不同的格式字符串得到类似 E 记法的结果。
如果你想在一个 print
语句中放人多个格式化字符串,该怎么办呢?你可以这样做:
>>> math = 75. 4
>>> science = 82.1
>>> print('I got %.1f in math and %.1f in science' % (math, science))
可以在 print
语句中放入任意多个格式化字符串,后面跟一个变量元组(tuple)。元组和列表很像,只是它使用的是圆括号而不是方括号,而且元组是不可变的。这是 Python 显得很挑剔的一个地方,这里你必须使用元组,而不能使用列表。除非只有一个变量需要格式化,这时才可以不用元组。请确保(引号内的)格式化字符串的数量和(引号外的)变量数量相同,否则程序会报错。
数字格式化
打印数字时,我们希望对数字如何显示有一些控制:
- 显示多少位小数;
- 使用常规记法还是 E 记法;
- 是否增加前导或末尾的 0;
- 是否在数字前面显示正负号(+或-)。
利用格式字符串,Python 为我们提供了充分的灵活性,不仅可以完成这些工作,甚至还可以做更多事情!
Today's High: 72.45672132, Low: 45.4985756
Today's High: 72, Low: 45
假设我们想要打印一个有两位小数的浮点数:
>>> dec_number = 12.3456
>>> print('It is %.2f degrees today.' % dec_number)
It is 12.35 degrees today
print
语句中间包含一个格式字符串。不过这一次没有直接使用 %f
,而是使用了%.2f
。这就告诉 Python 要采用浮点数格式,而且小数点后面要显示两位。(注意,Python非常聪明,它会正确地把数字四舍五人为两位小数,而不是直接去掉多余的数位。)
整数:%d 或 %i
要把某项内容打印成整数,可以使用 %d
或 %i
格式字符串。
number = 12.67
>>> print('%i' % number)
12
>>> print(number)
12.67
注意,这一次数字没有四舍五人。它被截断(truncated,表示“直接切断”)了。如果是四舍五人,我们会看到13而不是12。使用整数格式化时,数字会被截断,不过使用浮点数格式化时,数字则会四舍五人。number
的值并没有改变。我们只是使用格式字符串采用不同的方式打印。
这里要注意以下3个方面:
- 字符串中不要求有其他文本,可以只包含格式字符串。.
- 即使是浮点数,也可以把它打印为整数。这可以通过格式字符串实现。
- Python会把值截断为上一个最大整数”。不过,这与
int()
函数不同,因为格式字符串不会像int()
那样创建一个新的值,而只是改变值显示的方式。
浮点数:%f 或 %F
打印小数时,可以在格式字符串中使用大写或小写的 f (%f
或 %F
) :
>>> number = 12.3456
>>> print('%f' % number)
12.345600
如果只使用 %f
,数字会显示为有6位小数。如果在 f 前面加上 .n
, 这里 n
可以是任意整数,就会把数字四舍五人为指定的小数位数:
>>> print('%.2F' % number)
12.35
可以看到它把数字 12.3456
四舍五人到小数点后前两位:12.35
。
如果指定的小数位比数中实际的小数位还要多,Python 会用 0
来填充(pad
):
>>> print('%8.8f' % number)
12.34560000
这个数的小数点后面只有 4
位,但我们要求有 8
位小数,所以另外 4
位会用 0
来填充。
如果是负数,%f
总会显示 -
号。如果希望数字总会显示正负号(即使它是一个正数),可以在 %
后面加一个 +
号(如果列表中既有正数也有负数,这对于列表的对齐也很有好处):
>>> print('%+f' % number)
+12.345600
如果希望包含正负数的列表对齐,但是不希望看到正数带 +
号,可以在 %
号后面使用一个空格代替 +
:
>>> number2 = -98.76
>>> print('% .2f' % number2)
-98.76
>>> print('% .2f' % number2)
12.35
输出中的 12
前面有一个空格,所以,尽管 98
前面有负号而 12
前面没有正负号,这两个数也能对齐。
E记法:%e 或 %E
要使用 e格式
字符串打印 E记法
。它总是打印 6
位小数,除非你另作要求。
>>> number = 12. 3456
>>> print('%e' % number)
1.234560e+01
如果要打印更多或更少的小数位,可以在号后面使用 .n
,就像打印浮点数时一样:
>>> number = 12. 3456
>>> print('%.3e' % number)
1.235e+01
>>> print('%.8e' % number)
1.23456000e+01
%.3e
四舍五人为3位小数,%.8e
增加了一些 0
来填充不足的小数位。
小写或大写e都是可以的,你在格式字符串中使用什么大小写形式,输出时也会显示同样的大小写:
>>> print('%E' % number)
1.234560E+01
浮点数或E记法:%g 或 %G
如果你希望 Python 自动选择浮点数记法或E记法,可以使用 %g
格式字符串。同样,如果使用大写,输出中就会得到一个大写的E:
>>> number1 = 12.3
>>> number2 = 456712345.6
>>> print('%g' % number1)
>>> print('%g' % number2)
12.3
4.56712e+08
Python 会为大数自动选择E记法,而对较小的数使用浮点数记法。
存储格式化结果
有时你不想直接打印出格式化的数字,而是希望把它存储在一个字符串中以备以后使用。这很容易,可以不打印,把它直接赋给一个变量,如下:
>>> my_string = '%.2f' % 12.3456
>>> print(my_string)
12.35
>>> print('The answer is ' + my_string)
The answer is 12.35
这里没有直接打印格式化数字,我们把它赋给变量 my_string
。再将 my_string
与其他一些文本结合,并打印整个句子。
format() 方法
Python 字符串有一个名为 format()
的方法。它的工作方式和在前面见过的 %
格式化字符串很像。事实上,格式化说明符号 f、g、e
等都是一样的,只不过使用方式稍有区别:
math = 80.333
science = 98.20384
print('I got {0:.1f} in math, {1:.1f} in science'.format(math, science))
在这种方法中,格式化说明符被放在花括号中,而不再以 %
开头。0 和 1 告诉 Python 要格式化的是元组中的哪个变量。Python 计数从 0 开始,所以元组中第一个元素(变量 math)的索引是 0,第二个元素(变量 science)的索引是 1。然后使用 .1f
。
也可以用 %
格式化,将格式化后的字符串存为一个变量:
distance = 149597870700
myString = 'The sun is {0: .4e} meters from the earth'.format(distance)
因为不再使用 %
来区分格式化字符串,所以如果要打印一个 %
的话,也不需要再做任何特殊工作:
>>> print('I got {0:.1f}% in math'.format(math))
I got 87% in math
Padding and aligning
右对齐
'%10s' % ('test',)
'{:>10}'.format('test')
#' test'
'%4d' % (42,)
'{:4d}'.format(42)
#' 42'
'%04d' % (42,)
'{:04d}'.format(42)
#'0042'
'%06.2f' % (3.141592653589793,)
'{:06.2f}'.format(3.141592653589793)
#'003.14'
左对齐
'%-10s' % ('test',)
'{:10}'.format('test')
#'test '
'{:_<10}'.format('test')
#'test______'
居中对齐
'{:^10}'.format('test')
#' test '
'{:^6}'.format('zip')
#' zip '
Truncating
.
后面的数字决定了截取的长度
'%.5s' % ('xylophone',)
'{:.5}'.format('xylophone')
#'xylop'
对齐、截取结合使用
'%-10.5s' % ('xylophone',)
'{:10.5}'.format('xylophone')
#‘xylop ’
Signed numbers
'%+d' % (42,)
'{:+d}'.format(42)
#'+42'
'{:=5d}'.format(-23)
#'- 23'
'{:=+5d}'.format(23)
#'+ 23'
Placeholders
data = {'first': 'Hello', 'last': 'Hodor!'}
'%(first)s %(last)s' % data
'{first} {last}'.format(**data)
'{first} {last}'.format(first='Hello', last='Hodor!')
'{first} {last}'.format(first=data['first'], last=data['last'])
#'Hello Hodor!'
person = {'first': 'Jean-Luc', 'last': 'Picard'}
'{p[first]} {p[last]}'.format(p=person)
#'Jean-Luc Picard'
data = [4, 8, 15, 16, 23, 42]
'{d[4]} {d[5]}'.format(d=data)
'23 42'
Datetime
from datetime import datetime
'{:%Y-%m-%d %H:%M}'.format(datetime(2021, 2, 3, 4, 5))
#'2021-02-03 04:05'
Parametrized
'{:{align}{width}}'.format('test', align='^', width='10')
#' test '
'%.*s = %.*f' % (3, 'Gibberish', 3, 2.7182)
'{:.{prec}} = {:.{prec}f}'.format('Gibberish', 2.7182, prec=3)
#'Gib = 2.718'
'%*.*f' % (5, 2, 2.7182)
'{:{width}.{prec}f}'.format(2.7182, width=5, prec=2)
#' 2.72'
dt = datetime(2021, 2, 3, 4, 5)
'{:{dfmt} {tfmt}}'.format(dt, dfmt='%Y-%m-%d', tfmt='%H:%M')
#'2021-02-03 04:05'
'{:{}{}{}.{}}'.format(2.7182818284, '>', '+', 10, 3)
#' +2.72'
'{:{}{sign}{}.{}}'.format(2.7182818284, '>', 10, 3, sign='+')
#' +2.72'
Custom Object
class HAL9000(object):
def __format__(self, format):
if (format == 'open-the-pod-bay-doors'):
return "I'm afraid I can't do that."
return 'HAL 9000'
pass
'{:open-the-pod-bay-doors}'.format(HAL9000())
#'I'm afraid I can't do that.'
Revision
- 如何调整垂直间隔(添加或删除换行符)。
- 如何用制表符设置水平间隔。
- 如果使用格式字符串显示不同的数字格式。
- 使用格式字符串的两种方法:
%
符号和format()
方法。
测试题
如果有两个单独的
print
语句,如下,怎样把所有内容都打印在同一行上?print("What is") print("your name?")
打印时如何增加额外的空行?
- 实现按列对齐时要使用哪一个特殊打印代码?
- 使用哪个格式字符串强制按E记法打印一个数?
动手试一试
编写一个程序,询问一个人的姓名、年龄和最喜欢的颜色,然后打印在一句话里。运行这个程序时应该看到类似这样的结果:
What is your name? Sam How old are you? 12 What is your favorite color? green Your name is Sam you are 12 years old and you like green
编写一个乘法表程序,使用制表符确保所有内容都能很好地按列对齐。
- 编写一个程序计算8的所有分数(例如,1/8, 2/8, 3…..直到8/8),要显示3位小数。