所以它是一个CPython的东西,不太确定它与其他实现有相同的行为.
但'{0}'.format()比str()和更快'{}'.format().我发布了Python 3.5.2的结果,但是,我尝试使用Python 2.7.12并且趋势是相同的.
%timeit q=['{0}'.format(i) for i in range(100, 100000, 100)]
%timeit q=[str(i) for i in range(100, 100000, 100)]
%timeit q=['{}'.format(i) for i in range(100, 100000, 100)]
1000 loops, best of 3: 231 µs per loop
1000 loops, best of 3: 298 µs per loop
1000 loops, best of 3: 434 µs per loop
Run Code Online (Sandbox Code Playgroud)
从文档上object.__str__(self)
由
str(object)内置函数调用format()并print()计算对象的"非正式"或可打印的字符串表示形式.
所以,str()并format()调用相同的object.__str__(self)方法,但速度的差异来自哪里?
更新
@StefanPochmann和@Leon在评论中指出,他们得到了不同的结果.我尝试用它来运行它python -m timeit "...",它们是正确的,因为结果是:
$ python3 -m timeit "['{0}'.format(i) for i in range(100, 100000, 100)]"
1000 loops, best of 3: 441 usec per loop
$ python3 -m timeit "[str(i) for i in range(100, 100000, 100)]"
1000 loops, best of 3: 297 usec per loop
$ python3 -m timeit "['{}'.format(i) for i in range(100, 100000, 100)]"
1000 loops, best of 3: 420 usec per loop
Run Code Online (Sandbox Code Playgroud)
所以似乎IPython正在做一些奇怪的事......
新问题:将对象转换为str速度的首选方法是什么?
由于某些原因,IPython时序刚刚关闭(但是,当在不同的单元格中使用较长格式的字符串进行测试时,它表现得稍好一些).也许在相同的单元格中执行是不对的,不知道.
无论哪种方式,"{}"都比"{pos}"它快一点,比"{name}"它们慢得多str.
str(val)是将对象转换为最快的方法str; 它直接调用对象' __str__(如果存在),并返回结果字符串.其他的,比如format,(或str.format)由于额外的函数调用(对format自身)而包括额外的开销; 处理任何参数,解析格式字符串然后调用__str__它们的args.
对于str.format方法"{}"使用自动编号; 从文档中的一小部分格式语法:
版本3.1中更改:位置参数说明符可以省略,因此
'{} {}'等效于'{0} {1}'.
也就是说,如果您提供表单的字符串:
"{}{}{}".format(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
CPython 立即知道这相当于:
"{0}{1}{2}".format(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
使用包含表示位置的数字的格式字符串; CPython不能假设一个严格增加的数字(从头开始0)并且必须解析每一个括号以使其正确,在此过程中减慢一些事情:
"{1}{2}{0}".format(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
这就是为什么它也不允许将这两者混合在一起:
"{1}{}{2}".format(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
ValueError当你试图这样做时,你会得到一个好的回报:
ValueError: cannot switch from automatic field numbering to manual field specification
Run Code Online (Sandbox Code Playgroud)
它也抓住了这些定位PySequence_GetItem,我很确定它是快速的,至少与PyObject_GetItem[见下一个]相比.
对于"{name}"值,CPython总是有额外的工作要做,因为我们处理的是关键字参数而不是位置参数; 这包括为调用构建字典以及生成LOAD用于加载keys和值的更多字节码指令的方法.函数调用的关键字形式总是会引入一些开销.此外,PyObject_GetItem由于其通用性质,实际使用的抓取似乎会产生一些额外的开销.