在Python中格式化字符串的方式有很多种。
第一种是传承自C语言printf
函数的使用%
占位符格式化字符串,如'%d' % 100
,这种方式严格来说是使用%
作为算数运算符进行的二元运算,而且有一个限制是只能进行数字和字符串的格式化输出。
第二种是str.format()
方法,用法如'{}'.format(1)
,等价于str.format('{}',1)
str.format()
可以格式化实现了__str__()
魔法方法的所有类型,如列表'{}'.format([1,2,3])
和字典'{}'.format({'a':1, 'b':2})
。
str.format()
在格式化多个对象的时候可以自由调整对象位置或者一个对象在字符串中出现多次,如'{1}{0}{1}'.format('a','b')
,得到'bab'
。
str.format()
还可以进行键值传递,如'{name} is {age} years ago.'.format(name = 'Mike', age= 18)
。
f-string模板字符串是Python3.6之后版本的新特性,类似于str.format()方法,但是简洁了很多,在字符串前加f标记后可以直接直接解析大括号里的表达式,并且内部的实现方法也有不同,比str.format()方法快很多。
>>>name = 'Mike'
>>>age = 18
>>>f'{name} is {age + 1} years old.'
'Mike is 19 years old.'
我们可以用Jupyter Notebook中%timeit
标记来测试这三种字符串格式化方法的效率。
%timeit '%d' %1
154 ns ± 3 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit '%s' %'a'
55.2 ns ± 0.223 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit '{}'.format(1)
261 ns ± 5.67 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit '{}'.format('a')
160 ns ± 7.32 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit '{}'.format(1,2,3)
836 ns ± 29.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit f'{1}'
11.7 ns ± 0.0736 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
%timeit f'{"a"}'
11.7 ns ± 0.25 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
%timeit f'{1,2,3}'
12.2 ns ± 0.882 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
可以看到f-string最快,%
占位符次之,而str.format()
方法是最慢的。我们可以通过分析字节码来看一下这三种方法的内部实现。
from dis import dis
dis(lambda: '%d' % 1)
1 0 LOAD_CONST 1 ('%d')
2 LOAD_CONST 2 (1)
4 BINARY_MODULO
6 RETURN_VALUE
dis(lambda: '{}'.format(1))
1 0 LOAD_CONST 1 ('{}')
2 LOAD_ATTR 0 (format)
4 LOAD_CONST 2 (1)
6 CALL_FUNCTION 1
8 RETURN_VALUE
dis(lambda: f'{1}')
1 0 LOAD_CONST 1 (1)
2 FORMAT_VALUE 0
4 RETURN_VALUE
我们可以看到正如上文说到的%占位符事实上是一个二元运算符的算术运算,而str.format()
方法进行了函数调用,f-string则是新的Python字节码指令,也在底层进行了优化,所以f-string更快也是很显然的。
f-string在代码的简洁性和直观性上都很突出,并且有着明显的效率上的优势,希望这一方法成为大家平时编码过程中的首选,当然潜在意思就是希望大家尽快迁移到Python3.6及以上的版本了。
最后给大家介绍一下f-string的一些数字的格式化方法。
f'{20:b} {20:o} {26:x} {26:X}'
'10100 24 1a 1A'
f'{10:.3f}'
'10.000'
f'{123:05}'
'00123'
f'{123:5}'
' 123'
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。