前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python中最快的格式化字符串方式

Python中最快的格式化字符串方式

原创
作者头像
杜逸先
发布2018-08-29 10:54:28
1.9K0
发布2018-08-29 10:54:28
举报
文章被收录于专栏:追不上乌龟的兔子

在Python中格式化字符串的方式有很多种。

%占位符

第一种是传承自C语言printf函数的使用%占位符格式化字符串,如'%d' % 100,这种方式严格来说是使用%作为算数运算符进行的二元运算,而且有一个限制是只能进行数字和字符串的格式化输出。

str.format()

第二种是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模板字符串

f-string模板字符串是Python3.6之后版本的新特性,类似于str.format()方法,但是简洁了很多,在字符串前加f标记后可以直接直接解析大括号里的表达式,并且内部的实现方法也有不同,比str.format()方法快很多。

代码语言:txt
复制
>>>name = 'Mike'
>>>age = 18
>>>f'{name} is {age + 1} years old.'
'Mike is 19 years old.'

三种方式的效率比较

我们可以用Jupyter Notebook中%timeit标记来测试这三种字符串格式化方法的效率。

代码语言:txt
复制
%timeit '%d' %1
代码语言:txt
复制
154 ns ± 3 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
代码语言:txt
复制
%timeit '%s' %'a'
代码语言:txt
复制
55.2 ns ± 0.223 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
代码语言:txt
复制
%timeit '{}'.format(1)
代码语言:txt
复制
261 ns ± 5.67 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
代码语言:txt
复制
%timeit '{}'.format('a')
代码语言:txt
复制
160 ns ± 7.32 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
代码语言:txt
复制
%timeit '{}'.format(1,2,3)
代码语言:txt
复制
836 ns ± 29.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
代码语言:txt
复制
%timeit f'{1}'
代码语言:txt
复制
11.7 ns ± 0.0736 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
代码语言:txt
复制
%timeit f'{"a"}'
代码语言:txt
复制
11.7 ns ± 0.25 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
代码语言:txt
复制
%timeit f'{1,2,3}'
代码语言:txt
复制
12.2 ns ± 0.882 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

可以看到f-string最快,%占位符次之,而str.format()方法是最慢的。我们可以通过分析字节码来看一下这三种方法的内部实现。

代码语言:txt
复制
from dis import dis
代码语言:txt
复制
dis(lambda: '%d' % 1)
代码语言:txt
复制
  1           0 LOAD_CONST               1 ('%d')

              2 LOAD_CONST               2 (1)

              4 BINARY_MODULO

              6 RETURN_VALUE
代码语言:txt
复制
dis(lambda: '{}'.format(1))
代码语言:txt
复制
  1           0 LOAD_CONST               1 ('{}')

              2 LOAD_ATTR                0 (format)

              4 LOAD_CONST               2 (1)

              6 CALL_FUNCTION            1

              8 RETURN_VALUE
代码语言:txt
复制
dis(lambda: f'{1}')
代码语言:txt
复制
  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-string格式化数字

转换进制

代码语言:txt
复制
f'{20:b} {20:o} {26:x} {26:X}'
代码语言:txt
复制
'10100 24 1a 1A'

保留小数位数

代码语言:txt
复制
f'{10:.3f}'
代码语言:txt
复制
'10.000'

规定宽度,前导'0'’

代码语言:txt
复制
f'{123:05}'
代码语言:txt
复制
'00123'

规定宽度,前导空格

代码语言:txt
复制
f'{123:5}'
代码语言:txt
复制
'  123'

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • %占位符
  • str.format()
  • f-string模板字符串
  • 三种方式的效率比较
  • f-string格式化数字
    • 转换进制
      • 保留小数位数
        • 规定宽度,前导'0'’
          • 规定宽度,前导空格
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档