Python字符串格式化
在本教程中,我们将学习Python中可用的不同字符串格式化技术
旧方法
,即百分比(%)格式
(在Python 2和3中受支持)新方法,即string.format()(Python 2.6及更高版本)
最新方法,即f字符串-格式化的字符串文字(Python 3.6及更高版本)
百分比格式
C语言风格的%格式化是一种古老的,不建议使用的格式化字符串的方法,我们可能最终会在旧代码中看到。在这种方法中,使用%操作符来传递值。在字符串中,我们使用%
字符,后接格式说明符,以声明应如何插入该值;
示例1:使用%格式替换值
在此示例中,我们将执行字符串和整数的基本替换。
#!/usr/bin/env python3 name = 'hynman' drink = 'coffee' price = 3 message = 'Hey %s, this %s costs $%d.' % (name, drink, price) print(message)
该脚本的输出:
~]# python3 percent-formatting.py Hey hynman, This coffee costs .
其中
字符串中的
%s
表示插入字符串%d
表示将其替换为整数字符串中出现的%的数量必须与字符串后面的%之后的数据项的数量相匹配。
单个数据项(例如
name
)紧跟在最后一个%
之后。必须将多个数据分组为一个元组,因为我们在括号内添加了名称,饮料,价格,并用逗号分隔
下表显示了替换键的可能格式。
转换 | 意义 |
---|---|
%d | 有符号整数十进制 |
%i | 有符号整数十进制 |
%u | 过时-与“d”相同 |
%o | 符号八进制值 |
%x | 有符号十六进制-小写 |
%X | 有符号十六进制-大写 |
%f | 浮点十进制 |
%e | 浮动点指数小写 |
%E | 浮点指数大写 |
%g | 如果指数小于-4或者不小于精度,浮点格式使用小写指数格式,否则使用十进制格式 |
%G | 如果指数小于-4或者不小于精度,浮点格式使用大写指数格式,否则使用十进制格式 |
%c | 单个字符 |
%r | 字符串(使用repr()转换有效的Python对象) |
%s | 字符串(使用str()转换有效的Python对象) |
%% | 未转换任何参数,结果为“%”字符 |
示例2:添加填充并对齐字符串的内容
我们可以在%和类型说明符之间的格式字符串中添加其他值,以指定"最小和最大宽度","对齐"和"字符填充"。
初始的"%"字符。
可选的对齐字符:无或者" +"表示右对齐,"-"表示左对齐。
要使用的可选的
minwidth
字段宽度。可选的"。"字符,用于分隔" minwidth"和" maxchars"。
可选的" maxchars"(如果转换类型为s),表示要从数据值中打印多少个字符。如果转换类型为" f",即浮点整数,则此参数指定精度(小数点后要打印多少位数字)。
这听起来可能令人困惑,而且从理论上讲都是如此,所以让我们在下一个示例中使用它:
#!/usr/bin/env python3 name = 'root' message1 = 'How' message2 = 'are you?' ## no extra padding log = "Hey %s, %s %s " % (name, message1, message2) print(log) ## added extra padding before message1 log = "Hey %s, %10s %s " % (name, message1, message2) print(log) ## added extra padding before message1 and right aligned log = "Hey %s, %+10s %s " % (name, message1, message2) print(log) ## added extra padding before message1 and left aligned log = "Hey %s, %-10s %s " % (name, message1, message2) print(log) ## Max 3 characters allowed in message2 log = "Hey %s, %s %.3s " % (name, message1, message2) print(log) ## min width is 10 and max character allowed is 3 in message2 log = "Hey %s, %s %10.3s " % (name, message1, message2) print(log)
该脚本的输出:
~]# python3 string-formatting.py Hey root, How are you? Hey root, How are you? Hey root, How are you? Hey root, How are you? Hey root, How are Hey root, How are
其中
第一个打印语句是默认输出,没有其他格式
第二条打印语句-我们添加了其他填充空白。由于我们未指定+或者-,因此默认填充位于左侧
第三个打印语句-我们使用+号将右侧的文本与定义的填充宽度对齐以提供相应的空格,因此输出类似于第二个打印语句
第四个打印语句-我们正在使用-符号将左侧的文本与定义的填充宽度对齐以提供相应的空格,因此这次的'message1'在左侧与右侧的其他空格对齐。
第五条打印语句-我们在message2中定义了一个字符限制,其中。 (点)充当分隔符。因此,仅打印消息2的前3个字母。由于我尚未定义任何填充,因此文本将使用默认填充进行打印
第六条打印语句-我将字符限制与最小宽度(width.char limit)组合在一起,因此现在我们看到
message2
在左侧包含添加的空白填充
示例3:使用浮点数添加额外的空白和对齐方式更改
现在,我们将重复在上一个示例中对字符串所做的相同练习,唯一的区别是此处我们采用浮点数和不同的消息进行记录。
#!/usr/bin/env python3 name = 'root' float_num = 95.2 ## no extra padding log = "Hey %s, the number is: %f. Cheers!" % (name, float_num) print(log) ## added extra padding before float_num log = "Hey %s, the number is: %10f. Cheers!" % (name, float_num) print(log) ## ads a + sign to float_num. No whitespace added log = "Hey %s, the number is: %+10f. Cheers!" % (name, float_num) print(log) ## added extra padding after float_num in the right side as the text is left aligned log = "Hey %s, the number is: %-10f. Cheers!" % (name, float_num) print(log) ## Max 3 numbers allowed in float_num log = "Hey %s, the number is: %.3f. Cheers!" % (name, float_num) print(log) ## min width is 10 before float_num and max character allowed is 3 in float_num log = "Hey %s, the number is: %10.3f. Cheers!" % (name, float_num) print(log)
该脚本的输出:
~]# python3 string-formatting.py Hey root, the number is: 95.200000. Cheers! Hey root, the number is: 95.200000. Cheers! Hey root, the number is: +95.200000. Cheers! Hey root, the number is: 95.200000 . Cheers! Hey root, the number is: 95.200. Cheers! Hey root, the number is: 95.200. Cheers!
我在每个打印语句中添加了一些注释,这些注释应该可以自我解释。与我们使用字符串得到的输出相比,输出似乎有所不同。
使用string.format()进行字符串格式化
Python 3.x使用不同的格式设置系统,该系统比Python 2.x使用的系统更强大。
现在,print语句是一个函数。
格式字符串使用大括号{}创建替换字段。
括号中未包含的所有内容均视为文字,并且不进行任何对话。
如果需要将大括号作为文字包含在内,则可以使用'{{'和'}}来转义。
此格式化系统已反向移植到Python 2.6和Python 2.7.
基本的默认格式字符串如下所示:
#!/usr/bin/env python3 name = 'hynman' num = 4359 print('Hello {}, your roll number is {}'.format(name, num))
该脚本的输出:
~]# python3 positional-arg.py Hello hynman, your roll number is 4359
这里的{}考虑了.format()函数提供占位符的顺序。如果我们更改.format()值的顺序:
#!/usr/bin/env python3 name = 'hynman' num = 4359 print('Hello {}, your roll number is {}'.format(num, name))
该脚本的输出:
~]# python3 positional-arg.py Hello 4359, your roll number is hynman
因此,输出的顺序以及.format()占位符也已更改。
为了更好地控制string.format()的工作方式,字符串格式支持两种不同类型的展示位置"
位置参数:我们必须指定索引位置{index}以执行格式
keyword arguments:
这里我们将key替换为可以用花括号{{key}中的parameter的key来访问该值的value。
位置参数
使用位置参数,我们提供大括号" {}"内的索引位置。这些占位符由基于索引位置的.format()
函数中的相应值替换。就像Python列表一样,这里的索引值从第一个位置的" 0"开始。
我们将以现有示例为例,其中已更改.format()
中值的顺序,但是这次我们将在{}
中提供位置参数,以便将适当的值放置在模板中。
#!/usr/bin/env python3 name = 'hynman' num = 4359 print('Hello {1}, your roll number is {0}'.format(num, name))
该脚本的输出:
~]# python3 positional-arg.py Hello hynman, your roll number is 4359
但是,如果我们提供了.format()函数元组中不存在的索引位置,那么我们将得到IndexError
。
Traceback (most recent call last): File "positional-arg.py", line 6, in print('Hello {2}, your roll number is {0}'.format(num, name)) IndexError: tuple index out of range
关键字参数
关键字参数是传递给模板的名称/值对。我们可以直接在参数中关联名称和值,因此,当我们将参数传递给模板时,就不会造成混淆。关键字参数使我们不必担心在消息模板中对参数进行正确排序,并且阐明了每个值在print语句或者模板中的作用。
在此示例中,我使用了" {name}"和" {num}"作为关键字放置位置,并且这些参数在.format()函数中定义,用于替换
#!/usr/bin/env python3 print('Hello {name}, your roll number is {num}'.format(name='hynman', num=4395))
该脚本的输出:
~]# python3 keyword-arg.py Hello hynman, your roll number is 4395
但是,如果我们引用一个未定义的键,则将得到KeyError
。在这个例子中,我用未定义的test替换了num,因此得到KeyError。
Traceback (most recent call last): File "keyword-arg.py", line 3, in print('Hello {name}, your roll number is {test}'.format(name='hynman', num=4395)) KeyError: 'test'
使用string.format()进行高级格式化
与%
格式相似,我们可以通过在格式字符串中添加额外的语法来获得更具体的布局。对于格式设置方法,我们在可能为空的替换目标的标识之后使用冒号,然后使用格式说明符,该说明符可以命名字段大小,对齐方式和特定的类型代码。
这是在格式字符串中可以作为替换目标出现的形式结构,它的四个部分都是"可选的",并且必须在中间插入空格:
{fieldname component !conversionflag :formatspec}
在此替换目标语法中:
" fieldname"是一个可选的数字或者关键字,用于标识一个参数
" component"是零个或者多个" .name"或者" [index]"引用的字符串,用于获取参数的属性和索引值,可以省略以使用整个参数值。
" conversionflag"以"!"开头(如果存在),其后是" r"," s"或者" a",以对值调用" repr"," str"或者" ascii"内置函数,分别。
formatspec
以:
开头(如果存在),其后是指定值显示方式的文本,包括字段宽度,对齐方式,填充,小数精度等细节,并以可选数据结尾键入代码。
以下是一些使用示例的格式说明符
说明符 | 说明 |
---|---|
:@@@20 | 左对齐,宽度为20 |
:>20 | 右对齐,宽度为20 |
:^20 | 中心对齐,宽度为20 |
:06.2f | 浮点数精度的零填充 |
:*>10 | 星号垫右对齐,宽度为10 |
:=10 | 填充放在符号后面,如果有的话,放在数字前面。仅适用于数字类型 |
:+20 | 在数字左边加上一个符号,宽度为20 |
:-20 | 只在负数前加一个符号,左填充至20宽 |
:20 | 在正数上强制一个前导空格,或者在负数上强制一个“-”,左填充到20的宽度 |
:, | 强制千位逗号表示数字 |
:.2% | 表示百分比(.975表示97.50%) |
:%M/%d/%Y | 类型特定用法。在本例中为datetime |
0:#x | 将整数格式化为十六进制值0xhh |
0:#o | 将整数格式化为八进制值0oxx |
0:#b | 将整数格式化为二进制值0bxxxxxx |
示例1:使用string.format()向字符串和整数添加额外的空格填充
我们将使用高级格式化语法在此python脚本中向字符串和整数添加其他空格和填充:
该脚本的输出:
~]# python3 string-format-1.py Hello hynman, your roll number is 43578. Best of Luck Hello hynman, your roll number is 43578. Best of Luck Hello hynman , your roll number is 43578 . Best of Luck Hello hynman , your roll number is 43578 . Best of Luck Hello hynman, your roll number is +43578. Best of Luck Hello hynman, your roll number is 43578. Best of Luck
我们可以检查解释输出的单个打印语句的注释。
示例2:具有浮点数的高级格式化
在此示例中,我使用了字符串和浮点数。我们在每个打印语句中添加了不同类型的对齐方式和格式。
#!/usr/bin/env python3 name = 'hynman' num = 97.65 ## no additional formatting print('Hello {0}, you got {1} marks'.format(name, num)) ## add width of 10 characters for both placeholders print('Hello {0:10}, you got {1:10} marks'.format(name, num)) ## Right align to the width of 10 print('Hello {0:>10}, you got {1:>10} marks'.format(name, num)) ## Center align to the width of 10 print('Hello {0:^10}, you got {1:^10} marks'.format(name, num)) ## Left align to the width of 10 print('Hello {0:<10}, you got {1:<10} marks'.format(name, num)) ## Assigned a floating point format to num print('Hello {0}, you got {1:f} marks'.format(name, num)) ## truncating the floating point number to two characters after decimal for num print('Hello {0:s}, you got {1:.2f} marks'.format(name, num)) ## adds a field with a width of six characters and zero padding on the left for num print('Hello {0:s}, you got {1:06.2f} marks'.format(name, num))
该脚本的输出:
~]# python3 string-format-2.py Hello hynman, you got 97.65 marks Hello hynman , you got 97.65 marks Hello hynman, you got 97.65 marks Hello hynman , you got 97.65 marks Hello hynman , you got 97.65 marks Hello hynman, you got 97.650000 marks Hello hynman, you got 97.65 marks Hello hynman, you got 097.65 marks
使用f字符串进行字符串格式化
" f-strings"出现在Python 3.6中,现在是推荐的格式化字符串的方式。
在引号前直接输入字母" f"或者" F"。
将变量名或者表达式包括在大括号"({})"中,以将其值包含在字符串中。
就像上一节的"新样式"格式一样,但是格式格式字符串中没有format()
函数,也没有空括号({}
)或者位置括号({1}
)。
这是一个简单的示例,其中我们使用关键字参数,而不是将关键字定义为变量:
#!/usr/bin/env python3 name = 'hynman' num = 12345 print(f'Hello {name}, Your roll number is {num}')
该脚本的输出:
~]# python3 f-string-ex.py Hello hynman, Your roll number is 12345
在所有情况下,使用f字符串格式化比使用带有%运算符和str.format方法的C样式格式字符串要短。
示例1:使用f字符串添加其他填充和对齐方式
我们可以使用与string.format()相似的语法,使用f-strings添加额外的对齐方式和填充:
#!/usr/bin/env python3 name = 'hynman' num = 12345 ## default output without any additional formatting print(f'Hello {name}, Your roll number is {num}') ## add width of 10 characters for both placeholders print(f'Hello {name:10}, Your roll number is {num:10}') ## Right align to the width of 10 print(f'Hello {name:>10}, Your roll number is {num:>10}') ## Center align to the width of 10 print(f'Hello {name:^10}, Your roll number is {num:^10}') ## Left align to the width of 10 print(f'Hello {name:<10}, Your roll number is {num:<10}') ## Add asterisk to the integer and right align the content to total 10 char print(f'Hello {name}, Your roll number is {num:*>10}') ## Add zeroes to the integer and right align the content to total 10 char print(f'Hello {name}, Your roll number is {num:0>10}')
该脚本的输出:
~]# python3 f-string-ex.py Hello hynman, Your roll number is 12345 Hello hynman , Your roll number is 12345 Hello hynman, Your roll number is 12345 Hello hynman , Your roll number is 12345 Hello hynman , Your roll number is 12345 Hello hynman, Your roll number is ** ***12345 Hello hynman , Your roll number is 0000012345